帮我用C语言写一个完整的程序。要求如下,第一,输入若干行单词,每行有四个单词,每个单词由一到十个大写字母组成,单词之间用一个空格隔开。最后一行由一个“#”结束,识别到“#”结束输入。 第二,若不满足上述要求,如单词字数过多,每行单词不满足四个,则输出“请重新输入单词”。 第三,程序将上述单词识别后进行分组,每行以先后顺序分为两组。即每行前两个单词为一组,后两个单词为一组。将每行两组分别进行双交叉词判别,若为双交叉词则以以下条件重新排列输出。两个单词交叉放置,一个水平放置,另一个垂直放置,交叉点是两个单词都共用一个字母,而且交叉点遵循交叉靠前原则,即这公用的字母尽量在水平单词的前方,然后也尽量在垂直单词的上方。每组的第一个单词为水平单词。两组交叉词的水平单词在同一行。每个水平单词隔三个空格。第四,若不能构成双交叉词,则显示"Unable to make two crosses"。每组双交叉词间空一行。
时间: 2024-02-20 11:02:09 浏览: 78
好的,以下是我为您编写的程序。请注意,程序中有一些注释,解释了代码的一些细节。如果您有任何疑问,请随时问我。
```c
#include <stdio.h>
#include <string.h>
// 宏定义:单词的最大长度
#define MAX_WORD_LENGTH 10
// 宏定义:每行单词数
#define WORDS_PER_LINE 4
// 宏定义:每行两组单词数
#define WORDS_PER_GROUP 2
// 函数声明:判断两个单词是否为双交叉词
int is_double_cross_word(char word1[], char word2[]);
int main() {
// 定义变量
char words[WORDS_PER_LINE][MAX_WORD_LENGTH + 1]; // 存储输入的单词
int num_words = 0; // 当前输入的单词数
int num_lines = 0; // 当前输入的行数
// 循环读入单词,直到读到 # 为止
while (1) {
// 读入一行
char line[100];
fgets(line, sizeof(line), stdin);
// 判断是否读到 #
if (line[0] == '#' && strlen(line) == 2) {
break;
}
// 分割单词
char *p = strtok(line, " ");
int count = 0;
while (p != NULL) {
// 判断单词长度是否合法
if (strlen(p) > MAX_WORD_LENGTH) {
printf("请重新输入单词\n");
break;
}
// 存储单词
strcpy(words[count], p);
count++;
num_words++;
// 如果读到了一行的最后一个单词,进行分组和双交叉词判别
if (count == WORDS_PER_LINE) {
// 分组
char group1[WORDS_PER_GROUP][MAX_WORD_LENGTH + 1];
char group2[WORDS_PER_GROUP][MAX_WORD_LENGTH + 1];
for (int i = 0; i < WORDS_PER_GROUP; i++) {
strcpy(group1[i], words[i]);
strcpy(group2[i], words[i + WORDS_PER_GROUP]);
}
// 双交叉词判别
int is_cross1 = is_double_cross_word(group1[0], group2[0]);
int is_cross2 = is_double_cross_word(group1[1], group2[1]);
// 如果两组都是双交叉词,进行重新排列输出
if (is_cross1 && is_cross2) {
// 按照交叉位置进行重新排列
for (int i = 0; i < strlen(group1[0]); i++) {
if (group1[0][i] == group2[0][0]) {
// 找到交叉位置
// 输出水平单词
printf("%s", group1[0]);
// 输出交叉部分
for (int j = 1; j < WORDS_PER_GROUP; j++) {
for (int k = 0; k < i; k++) {
printf(" ");
}
printf("%c\n", group2[j][0]);
}
// 输出垂直单词
for (int k = 0; k < i; k++) {
printf(" ");
}
printf("%s\n", group2[0]);
// 输出交叉部分
for (int j = 1; j < WORDS_PER_GROUP; j++) {
for (int k = 0; k < i; k++) {
printf(" ");
}
printf("%c\n", group1[j][i]);
}
// 输出空行
printf("\n");
break;
}
}
} else {
printf("Unable to make two crosses\n");
}
// 清空单词数组
num_words = 0;
memset(words, 0, sizeof(words));
}
// 继续读入下一个单词
p = strtok(NULL, " ");
}
// 每读入一行,行数加一
num_lines++;
}
return 0;
}
// 函数定义:判断两个单词是否为双交叉词
int is_double_cross_word(char word1[], char word2[]) {
// 遍历第一个单词的每个字母
for (int i = 0; i < strlen(word1); i++) {
// 如果第二个单词包含第一个单词的某个字母
if (strchr(word2, word1[i]) != NULL) {
// 遍历第二个单词的每个字母
for (int j = 0; j < strlen(word2); j++) {
// 如果第一个单词包含第二个单词的某个字母
if (word1[i] == word2[j]) {
// 判断交叉位置是否合法
if (i < j || (i == j && strlen(word1) == strlen(word2))) {
return 1;
}
}
}
}
}
return 0;
}
```
阅读全文