如何每次输出不同排列的字符串?rand()+switch方案效率待优化
如何高效实现字符串变量的随机顺序输出?
你当前用rand()配合switch case的方案,在字符串数量较少时勉强能用,但字符串一多,不仅要写大量重复的case代码,还没法覆盖所有可能的随机排列,效率和扩展性都很差。更高效的方案是用Fisher-Yates洗牌算法,直接对字符串数组进行随机重排,步骤如下:
实现步骤
- 将字符串存入数组:把分散的字符串变量统一放到一个指针数组里,方便批量操作。
- 初始化随机种子:调用
srand(time(NULL))确保每次运行的随机序列不同(注意只需要初始化一次,不要放在循环里)。 - Fisher-Yates洗牌:从数组末尾开始,逐个将当前元素与随机选中的前面元素交换,生成均匀随机的排列。
- 输出洗牌后的数组:循环遍历数组,按顺序打印即可。
完整代码示例
#include <stdio.h> #include <stdlib.h> #include <time.h> int main() { // 将所有字符串存入数组 char *words[] = { "Malfeasance", "Portruding", "Jostled", "Gaelet", "Morpheus", "Star" }; int count = sizeof(words) / sizeof(words[0]); int which_case; // 保留你原代码的标记变量,可根据需求调整逻辑 // 初始化随机种子(仅需调用一次) srand(time(NULL)); // Fisher-Yates洗牌算法 for (int i = count - 1; i > 0; i--) { // 生成0到i之间的随机索引 int j = rand() % (i + 1); // 交换当前元素与随机选中的元素 char *temp = words[i]; words[i] = words[j]; words[j] = temp; } // 输出前5个字符串(和原代码输出数量一致,也可输出全部) printf("1. %s\n2. %s\n3. %s\n4. %s\n5. %s\nInput: ", words[0], words[1], words[2], words[3], words[4]); // 如果你需要标记which_case,可根据洗牌后的内容自定义判断逻辑 // 示例:按第一个元素匹配原case的标记,可根据实际需求修改 if (words[0] == "Malfeasance") { which_case = 1; } else if (words[0] == "Star") { which_case = 2; } else if (words[0] == "Gaelet") { which_case = 3; } return 0; }
方案优势
- 扩展性强:后续新增字符串只需在数组里添加元素,无需修改核心逻辑。
- 效率更高:Fisher-Yates洗牌时间复杂度为O(n),远优于手动编写大量case的冗余方案。
- 随机性均匀:能生成所有可能的排列,且每个排列出现概率相等,覆盖范围远大于手动case。
内容的提问来源于stack exchange,提问作者Jethro Garcia
相关产品推荐
相关产品推荐

