我需要在C中创建一个函数,它可以找出2个字符串是否来自相同的单词。从当前代码中可以看出,我将每个字符串加载到单独的数组中。我发现在数组中有单词,全部是小写字母,每个单词之间只有1个空格,没有所有非字母字符。我虽然,我可以对字符串进行排序并在它们上调用strcmp,但不能这样做,因为有原因,可以有“狗狗狗猫”和“狗猫”这样的字符串,这些字符串来自相同的单词,因此函数应返回1,但如果只是排序并使用strcmp则不会。所以我虽然,我可以合并所有重复的单词1然后排序和strcmp,但仍然有一个问题,当有像“狗”和“上帝”这样的词,这些是2个不同的单词,但功能排序后仍然会将它们视为相同。 “狗狗狗猫”“狗猫” - 同样的话 “HI HeLLO !!'”“嗨,,,你好嗨” - 同样的话 我会非常感谢任何帮助。我真的不知道如何创造它,我坐了很长时间,仍然无法想象它。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int sameWords( const char * a, const char * b)
{
char * array1=NULL;
char * array2=NULL;
int length1=0, length2=0, i=0, j=0;
while(a[i])
{
if(i>=length1)
{
length1+=250;
array1=(char*)malloc(length1*sizeof(char));
}
if(isspace(a[i]) && !isspace(a[i-1]))
{
array1[i]=a[i];
}
if(isalpha(a[i]))
{
array1[i]=tolower(a[i]);
}
i++;
}
while(b[j])
{
if(j>=length2)
{
length2+=250;
array2=(char*)malloc(length2*sizeof(char));
}
if(isspace(b[j]) && !isspace(b[j-1]))
{
array2[j]=b[j];
}
if(isalpha(b[j]))
{
array2[j]=tolower(b[j]);
}
j++;
}
}
int main()
{
sameWords("This' is string !!! ", "THIS stRing is !! string ");
return 0;
}
答案 0 :(得分:0)
您从函数sameWords
返回任何内容,其返回类型为int
。
答案 1 :(得分:0)
我不会假装被授予答案,但我也会为这类事情看一下正则表达式。
Does C or C++ have a standard regex library?
解决它需要几分钟,你用正则表达式分割字符串,小写它,然后迭代来查看常用单词。
答案 2 :(得分:0)
我要解决此问题的方法是创建一个像树一样的数据结构,您可以在其中插入单词。如果单词已经存在,则insert函数将不执行任何操作,否则,它会将其转换为小写并将其插入树中。然后你可以简单地将两个字符串转换为这些类型的树并比较树。
另一种方法是使用bash。虽然这可能不允许你分配,但如果你理解它的工作方式和原因,你应该能够编写模仿它的代码:
# string1 and string2 are simply strings with spaces separating words
s1="dog dog dog cat"
s2="cat dog"
# Convert to arrays
a1=( $(printf "%s\n" ${s1} | sort | uniq ) )
a2=( $(printf "%s\n" ${s2} | sort | uniq ) )
# Compare the result
if [ "${a1[*]}" == "${a2[*]}" ] ; then
echo "Same"
fi
答案 3 :(得分:0)
您已经了解了两种解决问题的方法。复杂的是将每个字符串拆分成单词,对它们进行排序,然后清除重复数据,这在排序数组中很容易。更容易的是将第一个字符串拆分为单词,在第二个字符串中搜索每个单词。然后以相反的方式做同样的事情:拆分第二个并检查第一个中的单词。
这两种方法都要求您拆分字符串。这也是你似乎在代码中遇到问题的地方。 (你有基本的想法来查看单词边界,但你似乎不知道如何存储单词。)
基本问题是:你如何表示单词,即C字符串的子串?有各种方式。您可以将指针与字符串长度一起使用到字符串中,也可以将它们复制到另一个缓冲区中。
这是一个将字符串a
拆分为单词然后检查是否可以在b
中找到每个单词的单词:
/*
* Return 1 if all words in a can be found in b,
* return 0 otherwise.
*/
int split_and_check(const char *a, const char *b)
{
int begin = -1; /* marker for beginning of word */
char word[80]; /* temporary buffer for current word */
int prev = 0; /* previously read char to detect word bounaries */
int len; /* current length of word */
int i;
i = 0;
while (1) {
if (isalpha(a[i])) {
if (!isalpha(prev)) {
begin = i;
len = 0;
}
if (len < 80) word[len++] = a[i];
} else {
if (len > 0) {
word[len] = '\0'; /* manually null-terminate word */
if (strstr(b, word) == NULL) {
/* fail on string mismatch */
return 0;
}
len = 0; /* reset word-length counter */
}
}
if (a[i] == '\0') break; /* check end here to catch last word */
prev = a[i++];
}
return 1;
}
当前单词存储在本地字符缓冲区word
中,长度为len
。请注意在'\0'
搜索word
之前,如何手动将零结束标记b
添加到word
:库函数strstr
在另一个中查找字符串。两个字符串都必须以零结尾。
这只是解决方案的一半。你必须反过来检查字符串:
int same_words(const char *a, const char *b)
{
if (split_and_check(a, b) == 0) return 0;
if (split_and_check(b, a) == 0) return 0;
return 1;
}
这还不是您问题的确切解决方案,因为字符串匹配是区分大小写的。我已经跳过了这一部分,因为它更容易:strstr
区分大小写,我不知道任何忽略这种情况的变体。