如何从c中的字符串中删除重复的字母?

时间:2016-08-19 15:24:25

标签: c arrays string

我希望在每一行中显示一个带k个字母的句子,并从整个字符串中删除重复的字母。我设法写了一个新的字符串所有K长度的单词 使用此代码

void subSent(char str[],int k) {
    int MaxLe,i,j,h,z=0,Length, count;
    char stOu[1000]={'\0'};

    Length=(int)strlen(str);
    MaxLe=maxWordLength(str);
    if((k>=1)&&(k<=MaxLe)) {
        for(i=0;i<Length;i++) {
            if((int)str[i]==32) {
                j=i=i+1;
            } else {
                j=i;
            }

            for(;(j<i+k)&&(Length-i)>=k;j++) {
                if((int)str[j]!=32) {
                    stOu[z]=str[j];
                } else {
                    stOu[z]=str[j+1];
                }
                z++;
            }
            stOu[z]='\n';
            z++;
        }
    }
}

但我正在努力解决只需一次保存一个字的部分。 例如 字符串=有一个好的日子 并且k = 1 我应该打印 H 一个 V Ë ñ 一世 C d ÿ

先谢谢!

1 个答案:

答案 0 :(得分:0)

你的subSent()例程带来了一些挑战:首先,它既不返回也不打印它的结果 - 你只能在调试器中看到它;第二个它叫maxWordLength()你没有提供。

虽然避免重复可能很复杂,但就算法而言,这并不难。由于您的所有单词都是固定长度,因此我们可以使用新单词k字母(加上一个换行符)来处理输出字符串,执行strncmp()。在这种情况下,新单词是添加的最后一个单词,所以当指针符合时我们退出。

我已经重新编写了下面的代码,并添加了一个复制消除程序。我不知道maxWordLength()做了什么,所以我把它别名为strlen()以使事情正常运行:

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

#define maxWordLength strlen

// does the last (fixed size) word in string appear previously in string
bool isDuplicate(const char *string, const char *substring, size_t n) {
    for (const char *pointer = string; pointer != substring; pointer += (n + 1)) {
        if (strncmp(pointer, substring, n) == 0) {
            return true;
        }
    }

    return false;
}

void subSent(const char *string, int k, char *output) {
    int z = 0;

    size_t length = strlen(string);
    int maxLength = maxWordLength(string);

    if (k >= 1 && k <= maxLength) {
        for (int i = 0; i < length - k + 1; i++) {

            int start = z;  // where does the newly added word begin

            for (int j = i; (z - start) < k; j++) {

                output[z++] = string[j];
                while (string[j + 1] == ' ') {
                    j++;  // assumes leading spaces already dealt with
                }
            }

            output[z++] = '\n';

            if (isDuplicate(output, output + start, k)) {

                z -= k + 1;  // last word added was a duplicate so back it out

            }

            while (string[i + 1] == ' ') {
                i++;  // assumes original string doesn't begin with a space
            }
        }
    }

    output[z] = '\0';  // properly terminate the string
}

int main() {
    char result[1024];

    subSent("HAVE A NICE DAY", 1, result);

    printf("%s", result);

    return 0;
}

我有点清理了你的空间规避逻辑但它可以被输入字符串上的前导空格触发。

<强>输出

subSent("HAVE A NICE DAY", 1, result);

H
A
V
E
N
I
C
D
Y

subSent("HAVE A NICE DAY", 2, result);

HA
AV
VE
EA
AN
NI
IC
CE
ED
DA
AY

subSent("HAVE A NICE DAY", 3, result);

HAV
AVE
VEA
EAN
ANI
NIC
ICE
CED
EDA
DAY