【问题标题】:C-program that searches through an array to find a sequence of characters搜索数组以查找字符序列的 C 程序
【发布时间】:2016-01-29 01:43:40
【问题描述】:

我只是 C 编程的初学者。请帮助我解决以下问题。

问题:一个程序搜索包含一系列字符的给定数组。这些字符被限制为字母 A、G、T 或 C。序列中的最后一个字符设置为代码 0,以便于检测到结尾。

在这里找不到我做错了什么,但不断出错。

/*A program that searches through a given array that contains a sequence of characters. These characters are restricted 
to be the letters A, G, T, or C. The last character in the sequence is set to be the code 0, so that the end is easily
detected. That array should be declared and initialized.*/

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
void input_sequence(int length,char input[]);
void search(char C[],char DNA[],int length);

int main(void) {
    //Given array
    char DNA[] = {'A', 'G', 'C', 'G', 'G', 'G', 'A', 'C', 'C', 'G', 'T', 'C', 
          'C', 'C', 'G', 'A', 'C', 'A', 'T', 'T', 'G', 'A', 'T', 'G', 
          'A', 'A', 'G', 'G', 'G', 'T', 'C', 'A', 'T', 'A', 'G', 'A', 
          'C', 'C', 'C', 'A', 'A', 'T', 'A', 'C', 'G', 'C', 'C', 'A', 
          'C', 'C', 'A', 'C', 'C', 'C', 'C', 'A', 'A', 'G', 'T', 'T', 
          'T', 'T', 'C', 'C', 'T', 'G', 'T', 'G', 'T', 'C', 'T', 'T', 
          'C', 'C', 'A', 'T', 'T', 'G', 'A', 'G', 'T', 'A', 'G', 'A', 
          'T', 'T', 'G', 'A', 'C', 'A', 'C', 'T', 'C', 'C', 'C', 'A', 
          'G', 'A', 'T', 'G', '\0'};
    int length,i=0,k;
    /*Program should repeatedly ask the user for two things: the length of a search sequence,
    and the search sequence itself*/
    /*The program should terminate when the length of the input sequence is zero or less*/
    do{
        printf("Enter length of DNA sequence to match: ");
        scanf("%d",&length);
        Search sequence array
        char input[length];
        //input sequence length has to be >0
        if(length>0){
            input_sequence(length,input[]);
            /*The elements of the search sequence may take on one of five characters: A,G,T,C and *. The
            meaning of the ‘*’ character is that it matches all four nucleotides: A,G,T and C.*/
            for(i=0; i<length; i++){
                k=0;
                if(input[i]!='A'&&input[i]!='G'&&input[i]!='T'&&input[i]!='C'&&input[i]!='*'){
                    printf("Erroneous character input ’%c’ exiting\n",input[i]);
                    k=1;
                }
                if(k==1)
                    break;             
            }
            if(k==0){
                search(input,DNA,length);
            }
            k=0;
        }
    }
    while(length>0);
    printf("Goodbye");

    return (EXIT_SUCCESS);
}

//Function to search for input sequence in the given array
void search(char C[],char DNA[],int length){
    int numFound = 0,i,foundIndex;
    bool found = false;
    for(i=0;i<length && !found;i++) {
        int n=0;
        char temp=C[i];
        if (temp==DNA[i]) {
            numFound++;
            if (numFound == length) {
                found = true;
                foundIndex = i - (length-1);
            }
        }
        else numFound = 0;
    }
    if (found)
        printf("Match of search sequence found at element %d\n",foundIndex);   
}

void input_sequence(int length,char input[]){
    int i;
    printf("Enter %d characters (one of AGTC*) as a search sequence: ",length);
    for(i=0; i<length; i++){
        scanf(" %c", &input[i]);
        }
}

【问题讨论】:

  • 请按 Ctrl+A 并删除并重新开始。嵌套的if 语句真是一团糟,没有人会那样做。另外,问题是什么?
  • 问题:一个程序搜索包含一系列字符的给定数组。这些字符被限制为字母 A、G、T 或 C。序列中的最后一个字符设置为代码 0,以便于检测到结尾。
  • 这不是我的问题,如果您有问题并想解决它,请在这里问。
  • 搜索排列
  • 您在寻找strstr()吗?

标签: c arrays function for-loop do-while


【解决方案1】:

这里以GNU C library regexp为例:

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

void search(const char *regexp_str, const char *DNA, int length)
{
    int reti;
    const char *p = DNA;
    const int n_matches = 5;
    regmatch_t m[n_matches];
    regex_t regex;
    (void)length;

    reti = regcomp(&regex, regexp_str, 0);
    if(reti) {
        printf("Could not compile regex: %s\n", regexp_str);
        return;
    }

    while(1) {//based on http://www.lemoda.net/c/unix-regex/
        int nomatch = regexec(&regex, p, n_matches, m, 0);
        if(nomatch) {
            printf ("No more matches.\n");
            return;
        }
        if(m[0].rm_so != -1) {
            int start = m[0].rm_so + (p - DNA);
            int finish = m[0].rm_eo + (p - DNA);
            printf("'%.*s' (bytes %d:%d)\n",
                    m[0].rm_eo - m[0].rm_so, m[0].rm_so + p,
                    start, finish);
        }
        p += m[0].rm_eo;
    }
    regfree(&regex);
}

int main(void) {
    const char *DNA = "AGCGGGACCGTCCCGACATTGATGAAGGGTCATAGACCCA"
                      "ATACGCCACCACCCCAAGTTTTCCTGTGTCTTCCATTGAG"
                      "TAGATTGACACTCCCAGATG";
    while(1) {
        int length;
        char input[256];

        printf("Enter length of DNA sequence to match: ");
        fgets(input, sizeof(input), stdin);
        length = strtol(input, NULL, 10);
        if(length <= 0) {//input sequence length has to be >0
            break;
        } else if(length >= (int)(sizeof(input) - 1)) {
            printf("ERROR: Too big length=%d, max supported length=%d\n",
                   length, sizeof(input) - 1);
            break;
        }

        while(1) {
            const char *validInputs = "AGTC*";
            printf("Enter %d characters (one of AGTC*) as a search sequence: ",length);
            fgets(input, sizeof(input), stdin);

            int valid = 1;
            for(int i = 0; i < length; i++) {
                if(strchr(validInputs, input[i]) == NULL) {
                  printf("Erroneous character input '%c' in '%s'\n", input[i], input);
                  valid = 0;
                  break;
                }
            }
            if(valid) {
                break;
            }
        }
        input[length] = 0;
        //substitute '*' on '.' for using in regexp
        char *ptr = input;
        while((ptr = strchr(ptr, '*')) != NULL) {
            *ptr = '.';
        };
        printf("search for: %s\n", input);
        search(input, DNA, length);
    }
    printf("Goodbye\n");
    return (EXIT_SUCCESS);
}

另外使用 C++11 std::regex(只需要更改search()):

#include <regex>
#include <iterator>

void search(const char *C, const char *DNA, int )
{
    std::regex regex(C);
    std::string str(DNA);
    auto words_begin = std::sregex_iterator(str.begin(), str.end(), regex);
    auto words_end = std::sregex_iterator();
    printf("Found %d matches:\n", std::distance(words_begin, words_end));
    for(std::sregex_iterator i = words_begin; i != words_end; ++i) {
        std::smatch match = *i;
        printf(" match: %s, pos=%d\n", match.str().c_str(), match.position());
    }
}

【讨论】:

  • 对不起,答案代码无法编译。编译器引发了许多错误和几个警告(ubuntu linux 14.04 上的 gcc)
  • @user3629249 谢谢,我修复了错误和警告(-Wall -Wextra -pedantic in gcc-5.1.0)
【解决方案2】:

在你的主函数中,这一行是一个问题:

search(input[],DNA[],length);

参数 1 和 2、input[] 和 DNA[] 不正确。该符号用于声明和初始化数组。调用这些数组时,除非您想要该数组中的特定元素,否则应将括号去掉。 尝试将其重写为:

search(input, DNA, length);

此外,您在 do while 循环的末尾缺少一个结束大括号。

【讨论】:

  • 如果你能看一下我最近编辑的代码
  • 这是编译器返回的内容: helpComm.c: In function 'main': helpComm.c:30: error: 'Search' undeclared (first use in this function) helpComm.c:34: error: 'input' undeclared (first use in this function) helpComm.c:34: error: expected expression before ']' token 如果你转到第 30 行,你会发现你做了一个注释,但没有使用 // 注释符号。此外,在第 34 行,您通过包含 [] 括号犯了与原始帖子类似的错误。
【解决方案3】:

基本思想是扫描数组,比较字符,直到找到所有匹配项。要实现您可以有两个指针,一个最初指向 DNA 阵列,另一个指向您的目标阵列。然后比较这两个字符,如果它们匹配,则将指针向前移动一步。如果匹配失败,将目标数组指针重置为第一个字符并将 DNA 指针向前移动一步。重新启动这些过程,直到所有匹配。 有一个非常有效的算法你可以看看,Boyer–Moore string search algorithm

如果你不想自己实现算法,有一个简单的内置函数strstr()。您将两个数组传递给它,它会返回第一个出现的位置。

【讨论】:

  • 请勿仅发布链接答案。
猜你喜欢
  • 2013-05-28
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-27
  • 1970-01-01
相关资源
最近更新 更多