2

k&r book (The C Programming Language) を使用して C でプログラムを作成する方法を学んでいますが、演習の 1 つに問題があります。文字列 s2 内の任意の文字と一致する文字列 s1 内の文字を検出して削除するように求めています。

したがって、s1 = "A"; とします。

そして s2 = "AABAACAADAAE"

「BCDE」を返してほしい

私はそれに向けて正しい道を進んでいることを知っています。プログラムをうまく設計する方法がわかりません。追加のヒントを教えてください。二分探索木アルゴリズムについて読み込もうとしましたが、このありふれたタスクには少し高度すぎると感じました。

みんな、ありがとう!

/* An alternate version of squeeze(s1, s2) that deletes each character in
 * s1 that matches any character in the string s2
 *
 * Angie@odfx.org
 */

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

void squeeze(char s[], char t[]);

char string[] = "BAD";
char sstring[] = "ABC";

int
main(void)
{
    squeeze(string, sstring);
    return 0;
}

void
squeeze(char s[], char t[])
{
    int i, j, d;

    d = 0;
    if(strstr(s, t) == NULL)
        printf("%c", s[i]);
    s[j] = '\0';
}
4

6 に答える 6

3

素晴らしい本。もし私があなたなら、セクション 2.8 の squeeze() とまったく同じように進めますが、直接比較 (s[i] != c) する代わりに、関数を作成して利用します。

 int contains(char s[], int c)

文字列 s に c が含まれている場合は 1 を返し、そうでない場合は 0 を返します。簡単なアプローチから始めます。それが機能する場合は、より複雑なソリューションでパフォーマンスを向上させることができます (バイナリ検索ですが、s2 の文字が特定の順序である必要はないことに注意してください)。

于 2009-01-07T02:08:29.323 に答える
2

二分探索は、これにはやり過ぎです。3 つのインデックスが必要です。1 つの index( i) をウォークスルーしs、1 つの index( k) をウォークスルーしt、1 つの index( ) を使用して、文字が存在しないために保持する必要がjある場所を追跡します。したがって、 の各文字について、 に含まれているかどうかを確認してください。そうでない場合は、 に保管してください。ststs

void squeeze(char *s, char *t) {
    int i, j, k;
    int found = 0;

    for(i = j = 0; s[i] != '\0'; i++) {
        found = 0;
        for(k = 0; t[k] != '\0' && (found == 0); k++) {
            if(t[k] == s[i]) {
                found = 1;
            }
        }

        if(found == 0) {
            s[j++] = s[i];
        }

    }

    s[j] = '\0';
}
于 2009-01-07T02:11:36.430 に答える
0
void squeeze(char s1[], char s2[])
{
    int i,j,k;
    char c;
    for(i=0;s2[i]!='\0';i++)
    {
        c=s2[i];
        for(j=k=0;s1[j]!='\0';j++)
            if(s1[j]!=c)
                s1[k++]=s1[j];
            s1[k]='\0';
    }
}
于 2013-11-27T20:25:56.080 に答える
0

You don't need a fancy binary search to do the job. What you need is a double for loop that check for occurrence of each char in one string in another, and copy the non-occurring chars into a third char array (which is your result).

Code can be something like the following (not tested!):

char *s1, *s2, *result; /* original strings and the result string */
int len1, len2; /* lengths of the strings */
for (i = 0; i < len1; i++) {
   for (j = 0; j < len2; j++) {
     if (s1[i] == s2[j]) {
       break;
     }
   }
   if (j == len2) {  /* s1[i] is not found in s2 */
     *result = s1[i]; 
     result++; /* assuming your result array is long enough */
   }
}
于 2009-01-07T02:00:05.500 に答える
0

これが私の非常に明確でシンプルな答えであり、論理的な説明があります。

#include<stdio.h>
void squeeze();

main 内に、テスト済みの文字列と、yourstringから削除したい文字を含むwantbedelete文字列を入力します。

int main() 
{

    char yourstring[] = "AABAACAADAAE";
    char wantbedelete[] = "A";

    squeeze(yourstring, wantbedelete);
    printf("%s", yourstring);

    return 0;
}

スクイーズ関数内のロジックは次のとおりです。

  • wantbedelete char by char内でループします
  • 次に、wantbedeleteで見つかったすべての文字について、文字全体をループします。
  • 次に、2 つの確立された文字が一致しない場合は比較し、その文字を yourstring から yourstring に更新 (保存) するため基本的にここでは新しいインデックス ( k ) を定義して追跡し、必要な文字のみを更新します。
  • ここでの秘訣は、削除する各文字をループしている外側のループに戻るたびにインデックスをリセットして、必要な文字列だけを取得することです。

ロジックをより明確に理解できるように、デバッガーを使用し、squeeze 関数内の各行をたどることを強くお勧めします。

void squeeze(char s1[], char s2[]) 
{
    int i, j, k;

    k = 0;
    for (i = 0 ; s2[i] != '\0' ; i++) /* loop for each char we want to delete with index i */
    {
        for (j = 0 ; s1[j] != '\0'; j++) /* loop for each char we want to keep with index j */
        {
            if (s2[i] != s1[j]) /* if the two chars do not match */
            {
                s1[k++] = s1[j]; /* update s1 with the char that we want to keep using index k */
            }
        }
        s1[k] = '\0'; /* since we update all char that we want to keep, the last char of index k must be empty */
        k = 0; /* reset index k so we will be ready for the next char that we want to delete from s1 */
    }
}
于 2022-02-14T00:13:29.350 に答える