首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

UVA 10361 Automatic Poetry:Schuttelreim 詩歌自動生成算法解析

     編輯:關於C語言

題目背景

Schuttelreim 是一種德語文字遊戲:給定第一句包含兩對尖括號 `s3s5` 格式的字符串,第二句以 `...` 結尾。要求輸出:第一句去除括號;第二句將 `...` 替換為 `s4s3s2s5`。

輸入輸出範例

Input:
3
ein kind haelt seinen< schn>abel <n>ur
wenn es haengt an der ...
weil wir zu spaet zur<> oma <k>amen
verpassten wir das ...
<d>u <b>ist
...

Output:
ein kind haelt seinen schnabel nur
wenn es haengt an der nabel schnur
weil wir zu spaet zur oma kamen
verpassten wir das koma amen
du bist
bu dist

核心算法

  1. 解析第一行:提取 s1, s2, s3, s4, s5(尖括號內容)
  2. 輸出第一行:拼接 s1+s2+s3+s4+s5
  3. 讀取第二行:去除尾部 `...`
  4. 輸出第二行:拼接 第二行內容 + s4 + s3 + s2 + s5

C語言實現(兩種解法)

解法一:字符級解析(推薦)

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

#define MAXN 110

void get_segment(char *s) {
    int i = 0;
    while ((s[i] = getchar()) != '\n') {
        if (s[i] == '<' || s[i] == '>') { s[i] = '\0'; break; }
        i++;
    }
    s[i] = '\0';
}

int main() {
    int n;
    char s1[MAXN], s2[MAXN], s3[MAXN], s4[MAXN], s5[MAXN], line[MAXN];
    scanf("%d", &n);
    getchar();  // 吸收換行
    while (n--) {
        get_segment(s1);
        get_segment(s2);
        get_segment(s3);
        get_segment(s4);
        get_segment(s5);
        gets(line);
        line[strlen(line)-3] = '\0';  // 去除 ...
        printf("%s%s%s%s%s\n", s1, s2, s3, s4, s5);
        printf("%s%s%s%s%s\n", line, s4, s3, s2, s5);
    }
    return 0;
}

解法二:整行讀取後處理

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

char s[200], m[200], p[5][200];

int main() {
    int n, i, j, q, k;
    scanf("%d ", &n);
    for (i = 0; i < n; i++) {
        q = k = 0;
        fgets(s, sizeof(s), stdin);
        fgets(m, sizeof(m), stdin);
        for (j = 0; j < strlen(s); j++) {
            p[q][k] = s[j];
            k++;
            if (s[j] == '<' || s[j] == '>') { p[q][k-1] = '\0'; k = 0; q++; continue; }
            printf("%c", s[j]);  // 輸出第一行(去括號)
        }
        p[q][k] = '\0';
        m[strlen(m)-4] = '\0';  // 去除 ...\n
        printf("%s%s%s%s%s\n", m, p[3], p[2], p[1], p[4]);
    }
    return 0;
}

關鍵點總結

難點處理方法
空括號 `<>`對應段為空字符串,代碼需正確處理
行尾換行符scanf 後用 getchar() 吸收,或 fgets 整行讀取
第二行長度最多 100 字符,含 `...`,需精確截取
多組測試用例外層循環 n 次,每次重置索引變量

算法複雜度

  • 時間:O(L) 其中 L 為字符串長度,單次掃描
  • 空間:O(L) 存儲分段字符串
  • 屬於字符串處理基礎題,考察輸入解析與輸出格式控制

延伸思考

此題本質是模式匹配與字符串重組。若擴展為:括號嵌套、多組括號、正則表達式替換,則需用更通用的解析器(如有限狀態機或遞歸下降)。但對於固定格式的 Schuttelreim,簡單分段拼接最高效。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved