あなたのアイデアは、一つの問題は、ここで
for(j=i; i<(len-removed);j++)
str[j]=str[j+1];
悪いされていないようにあなたはj
をインクリメントしておくが、条件i<(len-removed)
は永遠に真の を開催します。ある時点で、あなたはメモリの境界を越えてメモリを読み書きしようとします( のように)segfault
となります。あなたの問題は、正確にいくつかのdupplicate の文字が計算されないということです。
はのは
str[j]=str[j+1];
も非常に効率的ではないことをあなたが言ってみましょう。私はポイントを得る、str[j]
の次の文字にコピーしようとすると、\0
を見つけるまで。あなたの入力がabccccddddeee
、 であり、あなたがしようとしている1枚のコピーがひどく長いとします。
重複コピーの数を計算し、 memmove
を使用すると、一度にメモリブロック全体を移動する方が効率的です。
あなたのアプローチの代わりにmemmove
を使用してコードを修正しました。私はまた、 のコメントを複写の長さを計算する方法と、 のパラメータがmemmove
であると説明しました。私は通常 の紙を取って、手で最初にやってみると、より早くアイデアを得ることができます。
#include <stdio.h>
#include <string.h>
void removeddup(char *str){
int i;
int j;
int len= strlen(str)-1;
int removed = 0;
for(i=0; i < (len-removed);)
{
if(str[i]==str[i+1])
{
// we calculate the length of the duplicates
j = 0;
while(str[i] == str[i + ++j]);
// we have j duplicates of str[i] (counting str[i])
// we copy the rest of the string after the j-1 duplicates
// the destination is the next character after str[i] (str + i +1)
// the source is str[i+j]
//
// now we have to determine how many chars to copy. In general
// you do string_length - index_of_source + 1, which also copies
// the \0 string-terminating character.
//
// In your case
// string_length: len - removed + 1 (the +1 because you
// defined len := strlen(str)-1;
// index_of_source: i + j
// ==> len - removed + 1 - (i + j) + 1
// so
memmove(str + i + 1, str + i + j, len - removed + 1 - (i+j) + 1);
// now we set how many characters we've removed
removed += j - 1;
// we go the next character
i++;
}else{
i++;
}
}
}
int main(void)
{
char text[] = "abccccccdeeefffffffffffff";
printf("Original: %s\n", text);
removeddup(text);
printf("removed: %s\n", text);
return 0;
}
はまた、あなたが バッファへの書き込みアクセス権を持っている場合、このメソッドはのみ動作することに注意してください。文字列リテラル(const char *text = "abcdddd";
)、 を渡すと、segfault
が返されます。これは、文字列リテラルが読み取り専用メモリにあるためです。 `私は(LEN-除去)<`ので: `
は、ラインがwhile
は(J ++; iが<(LEN-除去)J = i)について` ;
while(condition);
// is equivalent to
while(condition)
{
}
で終了していることに注意してください変更されない場合、無限ループが発生する可能性があります。 – BLUEPIXY
@BLUEPIXY 'else {i ++; } ' – Barmar
あなたはどのようにあなたの関数を呼び出しますか? – AnT