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

C语言字符串数组分组异常:为何出现重复与遗漏?

问题描述

我是C语言初学者,对数组仍感到困惑。我尝试编写程序将42个按字母排序的名字数组分成7组,每组5个成员,分组规则为首尾交替:第一组包含第1个、最后1个、第2个、倒数第2个、第3个成员。以下是我编写的代码:

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

int main() {
    const char students[42][50] = {"Alde", "Amio", "Ande", "Ayuson", "Bacabac", "Bisares", "Caparuzo", "Castro", "Dela Cruz", "Devera", "Frias", "Gailo", "Galvez", "Gamboa", "Geronimo", "Gutierrez", "Hernandez", "Landoy", "Lasay", "Lopez", "Luna", "Manalang", "Maranguis", "Matro", "Mercado", "Millonte", "Morshed", "Naz", "Neri", "Ogbac", "Oredina", "Pardillo", "Pedido", "Perez", "Piedad", "Rodriguez", "Santos", "Sañosa", "Takeuchi", "Uy", "Ventura", "Villavicencio"};
    int numberOfStudents = sizeof(students) / sizeof(students[0]);
    int j = numberOfStudents - 1;
    int numberOfGroups = 7;
    int groupSize = 5;
    char group[7][5][50] = {};
    int m = 0;

    for (int l = 0; l < numberOfGroups; l++) {
        int x = 0;  // Reset x for each group
        for (int i = 0; i < groupSize; i++) {
            if (j >= 0) {
                strcpy(group[l][x], students[m]);  // Use m for the first student
                x++;
                strcpy(group[l][x], students[j]);  // Use j for the second student
                x++;
                j--;
                m++;
            }
        }
    }

    // Print the groups
    for (int y = 0; y < numberOfGroups; y++) {
        printf("Group %d:\n", y + 1);
        for (int k = 0; k < groupSize; k++) {
            printf("\t%s\n", group[y][k]);
        }
        printf("\n");
    }

    return 0;
}

目前第一组结果正确,但其余组出现名字重复和遗漏的情况,我无法理解原因,寻求解决帮助。


问题分析与修复

你的代码核心问题出在内层循环逻辑上:

  • 内层循环for (int i = 0; i < groupSize; i++)会执行5次,每次循环复制两个名字,这意味着每组会被塞入10个名字,但group[l]只有5个位置,直接导致x越界,覆盖其他组的内存,同时m和j被快速推进,后续组只能拿到重复或剩余的少量名字。
  • 按照你的分组规则,每组5个名字的顺序是前1、后1、前2、后2、前3,也就是每组需要从前面取3个,后面取2个,而非每次循环塞两个。

修复后的代码如下:

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

int main() {
    const char students[42][50] = {"Alde", "Amio", "Ande", "Ayuson", "Bacabac", "Bisares", "Caparuzo", "Castro", "Dela Cruz", "Devera", "Frias", "Gailo", "Galvez", "Gamboa", "Geronimo", "Gutierrez", "Hernandez", "Landoy", "Lasay", "Lopez", "Luna", "Manalang", "Maranguis", "Matro", "Mercado", "Millonte", "Morshed", "Naz", "Neri", "Ogbac", "Oredina", "Pardillo", "Pedido", "Perez", "Piedad", "Rodriguez", "Santos", "Sañosa", "Takeuchi", "Uy", "Ventura", "Villavicencio"};
    int numberOfStudents = sizeof(students) / sizeof(students[0]);
    int j = numberOfStudents - 1;
    int numberOfGroups = 7;
    int groupSize = 5;
    char group[7][5][50] = {};
    int m = 0;

    for (int l = 0; l < numberOfGroups; l++) {
        int x = 0;
        // 按规则填充当前组:前1、后1、前2、后2、前3
        strcpy(group[l][x++], students[m++]);
        strcpy(group[l][x++], students[j--]);
        strcpy(group[l][x++], students[m++]);
        strcpy(group[l][x++], students[j--]);
        strcpy(group[l][x], students[m++]);
    }

    // 打印分组结果
    for (int y = 0; y < numberOfGroups; y++) {
        printf("Group %d:\n", y + 1);
        for (int k = 0; k < groupSize; k++) {
            printf("\t%s\n", group[y][k]);
        }
        printf("\n");
    }

    return 0;
}

关键修复点

  1. 去掉错误的内层循环,直接按分组规则依次复制5个元素:先取前部一个(m递增),再取后部一个(j递减),重复两次后,再取第三个前部元素。
  2. 每组处理完后,m总计增加3,j总计减少2,刚好符合每组用3个前部元素、2个后部元素的规则,避免重复和遗漏。
  3. 严格控制x的递增范围,确保每组只填充5个元素,不会出现越界问题。

这样修改后,所有组都会按照预期规则生成,不会再出现重复或遗漏的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 22:14:53