2017-01-25 8 views
0

文字列に重複がある場合は、文字を削除する必要があります。今ではそれを行いますが、最後にゴミ箱の値を表示します。なぜそれがそれを行うかわからないので、どんな助けもいいと思う。 また、新しい文字列の長さをどのように出力するべきかわかりません。文字列配列はゴミ値を出力します

これは私のmain.cファイルです:

#include <stdio.h> 
#include <string.h> 
#include "functions.h" 

int main() { 

    char string[256]; 
    int length; 

    printf("Enter char array size of string(counting with backslash 0): \n"); 
/* 
    Example: The word aabc will get a size of 5. 
    a = 0 
    a = 1 
    b = 2 
    c = 3 
    /0 = 4 
    Total 5 slots to allocate */ 

    scanf("%d", &length); 

    printf("Enter string you wish to remove duplicates from: \n"); 
    for (int i = 0; i < length; i++) 
    { 
     scanf("%c", &string[i]); 
    } 

    deleteDuplicates(string, length); 

    //String output after removing duplicates. Prints out trash values! 
    for (int i = 0; i < length; i++) { 
     printf("%c", string[i]); 
    } 
    //Length of new string. The length is also wrong! 
    printf("\tLength: %d\n", length); 
    printf("\n\n"); 

    getchar(); 
    return 0; 
} 

出力正しくない文字列の末尾のprintf("%c", string[i]);プリントアウトゴミ値から。

deleteDuplicates機能はfunctions.cファイルに次のようになります。デフォルトでは、参照渡していないCで

void deleteDuplicates(char string[], int length) 
{ 
    for (int i = 0; i < length; i++) 
    { 
     for (int j = i + 1; j < length;) 
     { 
      if (string[j] == string[i]) 
      { 
       for (int k = j; k < length; k++) 
       { 
        string[k] = string[k + 1]; 
       } 
       length--; 
      } 
      else 
      { 
       j++; 
      } 
     } 
    } 
} 
+1

'文字列[Kここで

は、ハッシュのこの考えを示し、私はしばらく前に書いたいくつか変更されたコードです+ 1]; 'このアプローチは非常にinefあるご' deleteDuplicates'機能 – UnholySheep

+0

に(未定義の動作を引き起こす)範囲外にアクセスします不完全な文字を並べ替えたりハッシュしたりするほうが良いのではないでしょうか?また、 'fgets'を使って文字を読むのはなぜですか? – RoadRunner

答えて

0

関数が値渡しです。したがって、deleteDuplicates関数はメイン関数の長さを変更していません。参照渡しするように関数を変更すると、長さが変更されます。

コードを使用した例です。

関数呼び出しは次のようになります。

deleteDuplicates(string, &length); 

関数は次のようになります。

void deleteDuplicates(char string[], int *length) 
{ 
    for (int i = 0; i < *length; i++) 
    { 
     for (int j = i + 1; j < *length;) 
     { 
      if (string[j] == string[i]) 
      { 
       for (int k = j; k < *length; k++) 
       { 
        string[k] = string[k + 1]; 
       } 
       *length--; 
      } 
      else 
      { 
       j++; 
      } 
     } 
    } 
} 
+0

なぜ 'length'へのポインタを間接参照しないのですか?今度はどこでも 'i

+0

@YuriyIvaskevych良いキャッチ。私は簡単な例を追加し、関数内の実際のコードについては考えなかった。編集された答え。 – quickblueblur

+0

'string [k + 1]'がまだ範囲外です –

1

運動を行うために、よりefficentと安全な方法があります:

#include <stdio.h> 
#include <string.h> 

void deleteDuplicates(char string[], int *length) 
{ 
    int p = 1; //current 
    int f = 0; //flag found 
    for (int i = 1; i < *length; i++) 
    { 
     f = 0; 
     for (int j = 0; j < i; j++) 
     { 
      if (string[j] == string[i]) 
      { 
       f = 1; 
       break; 
      } 
     } 
     if (!f) 
      string[p++] = string[i]; 

    } 
    string[p] = '\0'; 
    *length = p; 
} 

int main() { 
    char aux[100] = "asdñkzzcvjhasdkljjh"; 
    int l = strlen(aux); 

    deleteDuplicates(aux, &l); 
    printf("result: %s -> %d", aux, l); 
} 

あなたはここに結果が表示されます: http://codepad.org/wECjIonL

又はそれ以上の洗練された方法は、ここで見つけることができます: http://codepad.org/BXksElIG

0

あなたは配列内の文字をハッシュすることによってO(n)ソリューションを実現することができます。

しかし、他の回答が投稿された場​​合、コードの現在の問題を解決するのに役立ちます。私はあなたにこれを行うより効率的な方法を示すことに決めました。

int hashing[256] = {0}; 

すべての値は、アレイ内の0ように設定します。

あなたは、このようなハッシュ配列を作成することができます。次に、スロットに0があるかどうかを確認することができます。これは、文字が訪問されていないことを意味します。毎回0が見つかった場合は、文字列に文字を追加し、そのスロットを1とマークします。これにより、重複する文字を追加することはできません。これは、0が見つかった場合にのみ追加されるためです。

これはどこでも使用される一般的なアルゴリズムであり、コードをより効率的にするのに役立ちます。

また、scanf()の代わりに、fgetsをユーザーからの入力の読み取りに使用する方が良いです。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 

#define NUMCHAR 256 

char *remove_dups(char *string); 

int main(void) { 
    char string[NUMCHAR], temp; 
    char *result; 
    size_t len, i; 
    int ch; 

    printf("Enter char array size of string(counting with backslash 0): \n"); 
    if (scanf("%zu", &len) != 1) { 
     printf("invalid length entered\n"); 
     exit(EXIT_FAILURE); 
    } 

    ch = getchar(); 
    while (ch != '\n' && ch != EOF); 

    if (len >= NUMCHAR) { 
     printf("Length specified is longer than buffer size of %d\n", NUMCHAR); 
     exit(EXIT_FAILURE); 
    } 

    printf("Enter string you wish to remove duplicates from: \n"); 
    for (i = 0; i < len; i++) { 
     if (scanf("%c", &temp) != 1) { 
      printf("invalid character entered\n"); 
      exit(EXIT_FAILURE); 
     } 
     if (isspace(temp)) { 
      break; 
     } 
     string[i] = temp; 
    } 
    string[i] = '\0'; 

    printf("Original string: %s Length: %zu\n", string, strlen(string)); 

    result = remove_dups(string); 

    printf("Duplicates removed: %s Length: %zu\n", result, strlen(result)); 

    return 0; 
} 

char *remove_dups(char *str) { 
    int hash[NUMCHAR] = {0}; 
    size_t count = 0, i; 
    char temp; 

    for (i = 0; str[i]; i++) { 
     temp = str[i]; 
     if (hash[(unsigned char)temp] == 0) { 
      hash[(unsigned char)temp] = 1; 
      str[count++] = str[i]; 
     } 
    } 

    str[count] = '\0'; 

    return str; 
} 

例入力:

Enter char array size of string(counting with backslash 0): 
20 
Enter string you wish to remove duplicates from: 
hellotherefriend 

出力:

Original string: hellotherefriend Length: 16 
Duplicates removed: helotrfind Length: 10 
関連する問題