You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带限制的最长公共子串:忽略非DNA碱基的C语言代码修改求助

问题描述

我有一个能查找并打印两条DNA链最长公共子串的函数,现在想添加校验逻辑,让程序忽略非碱基('A'、'T'、'C'、'G')的字符。比如字符串CCAATTFFA与CCAATTKA的有效公共子串应为CCAATTA。以下是我的代码,尝试在while循环中添加多种校验但都无效,请求帮助添加正确的校验逻辑:

void CommonSubStr(char *X, char *Y, long int m, long int n) {
    long int maxCommonChain = 0;  
    long int end = 0; 
    for (long int i = 0; i < m; i++) {
        for (long int j = 0; j < n; j++) {
            long int currentLength = 0;  
            long int x = i, y = j; 
            while (x < m && y < n && X[x] == Y[y]) {
                currentLength++;
                x++;
                y++;
            }

            if (currentLength > maxCommonChain) {
                maxCommonChain = currentLength;
                end = i + maxCommonChain - 1; 
            }
        }
    }

    if (maxCommonChain == 0) { 
        printf("No common substring found.\n");
        return;
    }

    long int start = end - maxCommonChain + 1; 
    for (long int i = start; i <= end; i++) { 
        if (X[i] == 'A' || X[i] == 'C' || X[i] == 'G' || X[i] == 'T') {
            printf("%c", X[i]);
        }
    }
    printf("\n");
}
解决方案

核心问题是原代码未在匹配前跳过非碱基字符,且匹配时未校验字符有效性。按以下步骤修改即可实现需求:

  1. 添加碱基校验辅助函数
    写一个工具函数简化碱基合法性判断,让代码更清晰:

    int is_valid_base(char c) {
        return c == 'A' || c == 'T' || c == 'C' || c == 'G';
    }
    
  2. 跳过外层循环的非碱基起始位
    外层循环遇到非碱基直接跳过,避免从无效字符开始匹配:

    for (long int i = 0; i < m; i++) {
        if (!is_valid_base(X[i])) continue;
        for (long int j = 0; j < n; j++) {
            if (!is_valid_base(Y[j])) continue;
            // 后续匹配逻辑
        }
    }
    
  3. 修改while循环的匹配逻辑
    在匹配过程中先跳过两侧的非碱基,再判断有效碱基是否相等:

    long int currentLength = 0;  
    long int x = i, y = j;
    long int current_end = x;
    while (x < m && y < n) {
        // 跳过X中的非碱基
        while (x < m && !is_valid_base(X[x])) x++;
        // 跳过Y中的非碱基
        while (y < n && !is_valid_base(Y[y])) y++;
        if (x >= m || y >= n) break;
        if (X[x] == Y[y]) {
            currentLength++;
            current_end = ++x;
            y++;
        } else {
            break;
        }
    }
    
  4. 修正最长子串的结束位置计算
    因为匹配过程中跳过了非碱基,原索引计算方式会出错,改为记录实际匹配到的有效碱基结束位置:

    if (currentLength > maxCommonChain) {
        maxCommonChain = currentLength;
        end = current_end - 1;
    }
    
  5. 简化输出逻辑
    此时最长公共子串已确保全为有效碱基,无需再判断:

    long int start = end - maxCommonChain + 1; 
    for (long int i = start; i <= end; i++) { 
        printf("%c", X[i]);
    }
    printf("\n");
    

完整修改后代码

#include <stdio.h>

int is_valid_base(char c) {
    return c == 'A' || c == 'T' || c == 'C' || c == 'G';
}

void CommonSubStr(char *X, char *Y, long int m, long int n) {
    long int maxCommonChain = 0;  
    long int end = 0; 
    for (long int i = 0; i < m; i++) {
        if (!is_valid_base(X[i])) continue;
        for (long int j = 0; j < n; j++) {
            if (!is_valid_base(Y[j])) continue;
            long int currentLength = 0;  
            long int x = i, y = j;
            long int current_end = x;
            while (x < m && y < n) {
                while (x < m && !is_valid_base(X[x])) x++;
                while (y < n && !is_valid_base(Y[y])) y++;
                if (x >= m || y >= n) break;
                if (X[x] == Y[y]) {
                    currentLength++;
                    current_end = ++x;
                    y++;
                } else {
                    break;
                }
            }
            if (currentLength > maxCommonChain) {
                maxCommonChain = currentLength;
                end = current_end - 1;
            }
        }
    }

    if (maxCommonChain == 0) { 
        printf("No common substring found.\n");
        return;
    }

    long int start = end - maxCommonChain + 1; 
    for (long int i = start; i <= end; i++) { 
        printf("%c", X[i]);
    }
    printf("\n");
}

// 测试用例
int main() {
    char X[] = "CCAATTFFA";
    char Y[] = "CCAATTKA";
    CommonSubStr(X, Y, 9, 8); // 输出CCAATTA
    return 0;
}

内容的提问来源于stack exchange,提问作者ms complaints

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 12:03:40