检查C中是否有两个字符串排列

时间:2014-06-06 18:30:30

标签: c string

我实际上试图制作一些程序,可以检查两个字符串是否相互排列。我解释一下:

如果我考虑:

Eagle

Hdjoh

(我在上一个问题中使用过这两个例子)。

我得到一个排列,并且排列参数是3.为什么?因为在字母表中:E + 3 = H,a + 3 = d等。

我使用了 unsigned char ,因为如果我在其中一个字符串中得到一个z,我想要(例如)z + 3 = c。


我开始做的事情:

#include <stdio.h>
#define N 20

int my_strlen(unsigned char *string){
    int length;
    for (length = 0; *string != '\0'; string++){
        length++;
    }
    return(length);
}

int main()
{
    unsigned char string1[N], string2[N];
    int test=0, i=0, length1, length2;
    scanf("%s", string1);
    scanf("%s", string2);

    length1=my_strlen(string1);
    length2=my_strlen(string2);

    if(length1==length2){
        for(i=0; i<length1; i++){
            if(string1[i]==string2[i]){
                test=1;
                }
                else{
                    test=0;
                }
        }
        printf("Test = %d", test);
    }
    else{
        printf("Error");
    }

    return 0;
}

我刚开始考虑它..所以目前我只是试着逐个字母地比较两个字符串。

问题:如果我尝试比较 Hello hello ,或 Hello Helqo 我得到Test = 1。

所以有人可以告诉我这里有什么问题吗?

非常感谢。


编辑1:

#include <stdio.h>
#define N 20

int my_strlen(unsigned char *string){
    int length;
    for (length = 0; *string != '\0'; string++){
        length++;
    }
    return(length);
}

int main()
{
    unsigned char string1[N], string2[N];
    int test=0, i=0, length1, length2;
    scanf("%s", string1);
    scanf("%s", string2);

    length1=my_strlen(string1);
    length2=my_strlen(string2);

    if(length1==length2){
        for(i=0; i<length1; i++){
            if(string1[i]==string2[i]){
                test=1;
                }
                else{
                    test=0;
                    break;
                }
        }
        printf("Test = %d", test);
    }
    else{
        printf("Error");
    }

    return 0;
}

现在是正确的。我会继续。


编辑2 - 6.7.14:

我实际上是该计划的“第二部分”。我正在寻找d,我验证它是否是一个排列。没那么容易,所以我需要一些建议,我是否必须编写其他功能来做到这一点?或者只是处理我的代码的这一部分:

if(length1==length2){
            for(i=0; i<length1; i++){
                if(string1[i]==string2[i]){
                    test=1;
                    }
                    else{
                        test=0;
                        break;
                    }
            }
            printf("Test = %d", test);
        }
        else{
            printf("Error");
        }

        return 0;
    }

我暂时写了这样的话:

if(length1==length2){
        for(i=0; i<length1; i++){
                for(d=0; d<255; d++){
                    if(string1[i]==string2[i] + d){
                        permutation=1;
                }
                else{
                    permutation=0;
                    break;
                }
                }
        }
        printf("\nPermutation = %d \nd = %d", permutation, d);
    }
    else{
        printf("Not a permutation");
    }

    return 0;
}

(我知道它不起作用,但我只是试过..)。

感谢提前帮助。

8 个答案:

答案 0 :(得分:2)

您只打印出最后一个字符比较的结果。

for(i=0; i<length1; i++){
            if(string1[i]==string2[i]){
                test=1;
                }
                else{
                    test=0;
                }
}

每次都经过并比较每个字符并更改测试。在循环结束时,仅输出最后一个字符比较。

答案 1 :(得分:1)

这是因为您的test变量会针对字符串中的每个字符进行更新。

对于字符串 Hello hello ,或 Hello Helqo ,最后一个字符相同({{ 1}}),因此在循环结束时,'o'更新为test

尝试使用 Hello Hellm ,您将获得1

答案 2 :(得分:1)

你可以考虑这样的问题。要使两个字符串成为有效的排列,那么 字符串中每个字符的字符距离必须相等。 因此,您可以检查第一个字符距离,然后循环其他字符 并验证距离是否相同。一旦不等于第一个字符距离,您就可以安全地断定它不是排列。

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

int main(void)
{
    int i;
    unsigned char string1[] = "test";
    unsigned char string2[] = "vguv";

    int slength1 = 4;
    int slength2 = 4;

    int distance;
    int is_permutation = 1;

    if (slength1 != slength2) {
        is_permutation = 0;
    }

    distance = (int)string2[0] - (int)string1[0];

    for (i=1; i<slength1; ++i) {
        if ( ((int)string2[i] - (int)string1[i]) != distance ) {
            is_permutation = 0;
            break;
        }
    }

    if (is_permutation) {
        printf("%s is a permutation of %s with distance %d\n", string1, string2, distance);
    } else {
        printf("%s is not a permutation of %s\n", string1, string2);
    }

    return EXIT_SUCCESS;
}

请注意我使用了静态定义的字符串和stringlengths。您在用户输入中阅读的原始方式很容易出现未定义的行为。声明一个固定长度的字符串(OP中为20),因此如果用户输入的字符串长于19,scanf将超出边界并调用未定义的行为。这非常糟糕,你应该阅读它。

答案 3 :(得分:0)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    char a[100], b[100];
    int size_a, size_b, i, j, flag;
    scanf("%s", &a);
    scanf("%s", &b);
    size_a = strlen(a);
    size_b = strlen(b);
    if(size_a!=size_b)                   //if size of both strings are      unequal then print and exit
    {
        printf("no");
        exit(0);
    }
    for(i=0;i<size_a;i++)               //compare every element of a with every element of b
    {
        for(j=0; j<size_b;j++)
    {
        if(a[i]==b[j])
        {
            b[j]=32;                //when elements matches add character 'space' there, of ASCII value 32
            flag++;                 //flag guards of every successful match
        }
    }
}
if(flag==size_a&&flag==size_b)
    printf("yes");
else
    printf("no");
return 0;

}

我写了这段代码,对我来说很好用

答案 4 :(得分:0)

bool IsPremutation(char* s1, char* s2, int sl1, int sl2)

{

if (sl1 != sl2)
{
    return false;
}

std::set<char> charset;

for (int index = 0;  index < (sl1 + sl2); index++)
{
    int source = (index) / sl1;

    if (source == 0)
{
    charset.insert(s1[index]);
    }
    else
    {
    charset.insert(s2[source - 1]);
    }
}

return charset.size() == sl2;

}

答案 5 :(得分:0)

我知道这是陈旧的,但答案的质量令人不安。首先,你并不是在寻找一种排列;你正在检查移位密码是否有两个不同的字符串。

接受答案的更清晰版本,处理您提到的案例转换:

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


int shifted(const char* a, const char* b, int* amount) {
    size_t len_a = strlen(a);
    size_t len_b = strlen(b);
    if (len_a != len_b) return 0;

    int shift_amount = *b - *a;
    for (; *a; a++, b++)
        if (tolower(*b) - tolower(*a) != shift_amount) return 0;

    *amount = shift_amount;
    return 1;
}

int main(void) {
    const char *a = "shift";
    const char *b = "tigU";

    int shift_amount = 0;
    if (shifted(a, b, &shift_amount))
        printf("Shifted by amount: %d\n", shift_amount);
    else
        printf("Not shifted\n");

    a = "shift";
    b = "shifT";
    if (shifted(a, b, &shift_amount))
        printf("Shifted by amount: %d\n", shift_amount);
    else
        printf("Not shifted\n");

    a = "shift";
    b = "shifv";
    if (shifted(a, b, &shift_amount))
        printf("Shifted by amount: %d\n", shift_amount);
    else
        printf("Not shifted\n");

    return EXIT_SUCCESS;
}

输出:

Shifted by amount: 1
Shifted by amount: 0
Not shifted

答案 6 :(得分:0)

#include <stdio.h>
#define possiblechars 256

int is_permutation(char *str1, char *str2)
{
    int count1[possiblechars] = {0};
    int count2[possiblechars] = {0};
    int i;

    //sets count arrays '0' for 256 times
    for (i = 0; str1[i] && str2[i]; i++)
    {
        count1[str1[i]]++;
        count2[str2[i]]++;
    }

    //interates until either string 1 or 2 hits null
    //increments individual indexes of the count arrays
    if (str1[i] || str2[i]){
        return 0;
    }

    //if different lengths, then return false
    for (i = 0; i < possiblechars; i++){
        if (count1[i] != count2[i]){
            return 0;
        }
    }
    return 1;
}

int main(int argc, char *argv[])
{
    char str1[] = "Eagle";
    char str2[] = "Hdjoh";
    if (is_permutation(str1, str2)){
      printf("Permutation\n");
    }
    else {
      printf("Not a permutation\n");
    }
    return 0;
}

答案 7 :(得分:0)

#include <stdio.h>
#include <conio.h>
#include <string.h>
#define N 20

int my_strlen(unsigned char *string)
{
    int length;

    for (length = 0; *string != '\0'; string++)
    {
        length++;
    }
    return (length);
}

int main()
{
    unsigned char string1[N], string2[N];
    int permutations = 0, i = 0, d = 0, length1, length2;
    scanf("%s", string1);
    scanf("%s", string2);
    length1 = my_strlen(string1);
    length2 = my_strlen(string2);
    d = string1[0] - string2[0];   //finding out the distance
    if (length1 == length2)
    {
        for (i = 0; i < length1; i++)
        {
            if (d < 0)           //if less then 0 then String2 >String1
            {
                if (string2[i] == string1[i] + d * (-1)) //when d enters here d will be always negative
                {
                    permutations=1;
                }
                else
                {
                    permutations = 0;
                    break;
                }
            }
            else           //else String1 >String2
            {
                if (string1[i] == string2[i] + d)
                {
                    permutations = 1;
                }
                else
                {
                    permutations = 0;
                    break;
                }
            }
        }
        printf("Permutations=%d\n and distamce=%d", permutations, d);
    }
    else
    {
        printf("Error");
    }
    return 0;
}