最近、コードフォースのプログラミングコンテストで質問に出くわしました。問題タグは、2つのポインター方式を使用することで問題を解決できることを示しています。ツーポインター法とは正確には何ですか?
4 に答える
これらのリンクで私が知ることができることから、「2 つのポインター メソッド」は、2 つの異なるインデックスを使用して 2 つの異なる配列にインデックスを付けることを単に指します (配列インデックスをポインターとして参照します。これは、ほとんどの C プログラマーが用語を使用する方法とは多少異なります)。 .
彼らは次のような問題のコンテキストでそれを使用していました
if (a[i] + b[j] == X)
// do something with i and j
ここでi
、 とj
はポインターでした (「ポインター」という用語の一般的な意味であり、C データ型の意味ではありません)。
これはそれほど風変わりなものではありません。今日まで、誰かが特定の用語を作り出したとは思いもしませんでした。
ほとんどの C プログラマーと話すとき、「2 ポインター メソッド」のような用語は、次のような二重逆参照を伴うものを意味します。
x = **p;
これは、codeforces リンクで彼らが話していることとはまったく異なります。
Google は「ツー ポインター メソッド」の 2350 件のヒットを報告していますが、最初の数ページではこのフレーズを使用してさまざまなアルゴリズムを参照しています。大文字にすることはほとんどありません。おそらく彼らは、コンテストを主催するグループに固有の他の議論や文献などですでに確立されているいくつかの代替案の1つに言及していた.
私はあなたがこのようなことについて話していると思います:
int **allocation(int n, int m) {
int **matrix;
int i;
matrix = (int **) malloc(sizeof(int *) * n);
for (i = 0; i < n; i++)
matrix[i] = (int *) malloc(sizeof(int) * m);
return matrix;
}
おそらく、ポインターへのポインターを持つことを意味していました。
C では、呼び出し元が所有するポインターを変更するために呼び出された関数が必要な場合などによく使用されます。
1 つの例として、バイナリ ツリーにツリー ノードを挿入する関数があります。
void tree_insert(Node **root, int value)
{
Node *here = *root;
if(here == NULL)
{
if((*root = malloc(sizeof ***root)) != NULL)
(*root)->value = value;
}
else if(value < here->value)
tree_insert(&root->left, value);
else if(value > here->value)
tree_insert(&root->right, value);
}
ツリーのルート (それ自体がポインター) へのポインターを渡すことにより、関数はそれを変更できます。
これを使用して、ツリーを次のように初期化できます。
Node *tree = NULL;
tree_insert(&tree, 42);
tree_insert(&tree, 4711);
この例では、もちろん関数からの戻り値を使用することもできますが、おわかりいただけたと思います。