不明な長さの文字列をスキャンしようとしている場合、一度に1文字ずつ入力をスキャンし、文字のリンクリストを作成して文字列を作成することをお勧めしますか?私が現在直面している唯一の問題は、ユーザーに一度に1文字ずつ文字列を入力するように求めずに、一度に1文字ずつ文字列を処理する方法がわからないことです。これは、不合理です。より良いアプローチはありますか?ほとんどの文字列に対応するためだけに、任意の大きなサイズのchar配列をmallocすることは避けたいと思います。
3 に答える
私の提案では、charのリンクリストを作成すると、1つの文字列に対してメモリを大量に消費するため、非常に悪い考えになります。
代わりに、公称サイズのバッファー(たとえば、128バイト)を割り当てて、文字を読み続けます。バッファがほぼいっぱいになったら、現在のサイズの2倍の別のバッファを割り当て、最初のバッファの内容を2番目のバッファにコピーして、最初のバッファを解放します。このように、文字列が完全に読み取られるまで続行できます。
また、私が書いたり見たりしたほとんどのプログラムでは、文字列サイズの上限が維持され、文字列入力がサイズを超えているように見える場合、プログラムはエラーを返します。文字列サイズの上限は、アプリケーションのコンテキストに基づいて決定されます。例:読み取っている文字列が名前の場合、通常は32文字(またはx値)を超えることはできません。超えている場合は、名前が切り捨てられてバッファに収まります。このようにして、バッファを最初に上限サイズに割り当てることができます。
これは1つのアイデアにすぎません。リンクリストではなく、これに対処できる他の多くの方法があるかもしれません。
node-per-charリンクリストの過剰なメモリ使用量をしばらく無視し、実際にそれを構築して文字列を組み込んだと仮定します。実際に使用できますか?
例えば:
- 連続していないバッファは、標準機能の多く(たとえば、、)
printf()
が単に互換性がないか、操作が面倒であることを意味しますstrlen()
。fwrite()
- 文字列への非シーケンスアクセスは非常に非効率的です。
より良いアプローチとして:それはあなたが文字列で何をしようとしているのかに本当に依存します。(たとえば、文字列が入ってくるときに処理できる場合は、すべてをメモリに保持する必要さえないかもしれません。)
配列に格納します。固定サイズの配列で配列を初期化し、入力の読み取り中にそれらを配列に格納します。配列がいっぱいになり、新しい入力が来たら、doubleサイズのより大きな配列を作成し、古い配列を新しい配列にコピーします。次に、この配列に新しい文字を追加し続けます。すべてのデータを読み取るまでこのプロセスを繰り返します。次の方法で、古い配列から新しい配列に文字をコピーするプロセスを最適化できます。
1)Initialize a variable old_idx to 0
2) When a new char comes (after the old array is full) then create a new array of double size of older one and copy the new char at old_size+1 index. Also copy the data at index old_idx in old array at old_idx in newer array.
3)Increment old_idx
最後に、old_idx <old_array_sizeの場合は、残りの古いデータをコピーすることを確認してください。
プロセス全体の償却コストはかなり低く、これがJavaのArrayListも機能する方法です。
リンクリストに対するアレイの利点は明らかです
1) Less memory footprint
2)Faster linear access (as in array all the memory allocations for data happen in contiguous manner)