我需要创建一个程序,要求用户输入一个字符串然后在程序中的函数需要将它分成2个相同大小的字符串(用户总是输入偶数个字符),然后它必须“洗牌” “他们......
所以基本上应该这样做:
user inputs: A1B1C1D1
代码应该生成两个大小相同的字符串:A1B1
和C1D1
,之后应该将它们“洗牌”,如下所示:A1C1B1D1
。
所以它需要取第一个字符串的前2个元素,然后是第二个字符串的前2个元素,依此类推......
我的问题是,当我输入A1B1C1D1
时,在运行程序之后,我得到AC1BD1
(它从第一个数组中省略了第二个字符)。
#include<stdio.h>
#include<string.h>
#define N 100
void shuffle(char *cards) {
int i, n, x=0, c1=0, c2=0, j=0;
char tmp1[N]={0}, tmp2[N]={0};
n=strlen(cards);
//divide to 2 arrays with same number of elements
for(i=0; i<n; i++){
if(i<(n/2)){
tmp1[i]=cards[i];}
else{
tmp2[x]=cards[i];
x++;
}
}
//storing 2 elements from first array, then 2 elements from second array and so on
for(i=0; i<n; i++){
if(j>3){
j=0;
}
if(j<=1){ // store 2 elements from 1st array
cards[i]=tmp1[c1];
c1++;
j++;
}
if(j>=2){ // store 2 elements from 2nd array
cards[i]=tmp2[c2];
c2++;
j++;
}
}
printf("1st half:%s\n2nd half:%s", tmp1, tmp2);
printf("\n\t%s",cards);
return;
}
int main() {
char cards[N];
scanf("%s", cards);
shuffle(cards);
return 0;
}
答案 0 :(得分:2)
问题出在这里
if(j<=1){ // store 2 elements from 1st array
cards[i]=tmp1[c1];
c1++;
j++;
}
if(j>=2){ // store 2 elements from 2nd array
cards[i]=tmp2[c2];
c2++;
j++;
}
将第二个if作为“else if”(只是“else”也足够)
当你将j从1增加到2之后,你会进入第二个if语句,然后在卡片上重写相同的索引。
答案 1 :(得分:2)
如果你不介意以更简单的方式“改变你的牌组”的替代建议:
void shuffle(char *cards)
{
char tmp[N]={0};
int n = strlen(cards);
for (int i=0; i<n/2; i++)
tmp[i*2+0] = cards[i];
for (int i=0; i<n/2; i++)
tmp[i*2+1] = cards[i+n/2];
for (int i=0; i<n; i++)
cards[i] = tmp[i];
}
答案 2 :(得分:0)
你称之为洗牌和卡牌。 制作一个有两个元素的卡片结构不是更好吗?
我认为你在for循环中的j表现不对。 我会仔细检查这个并编辑这个答案,如果它不是j。
编辑: 你的cradcount有点关闭,你写了错误的索引。 这是一些有效的代码:
j = 0;
i = 0;
while(i<n)
{
++j;
if(j == 1 || j == 2)
{ // store 2 elements from 1st array
cards[i++]=tmp1[c1++];
}
else if(j == 3 || j == 4)
{ // store 2 elements from 2nd array
cards[i++]=tmp2[c2++];
}
else
{
j = 0;
}
}
通常,您可以使用调试器查看索引发生的情况。我认为这是家庭作业,你必须写“最佳代码”。一般来说,使用具有更多含义的varaiblaenames是有益的。
EDIT2:
下面有一个很好的解决方案,说明时间优化代码。 我想添加一些我认为更容易阅读和维护的代码。
#include<stdio.h>
#include<string.h>
#define DECK_MAX 100
typedef struct
{
char group;
int number;
}Tcard;
typedef struct
{
Tcard card[DECK_MAX];
int count;
}Tdeck;
int ReadDeck(Tdeck * deck, const char *cardstring);
int DeckAddCopy(Tdeck * deck, Tcard * card);
int PrintDeck(Tdeck * deck, const char *deckname);
int InterleaveDecksCopy(Tdeck * target, Tdeck * source[], int sourcecount);
int SplitDeckCopy(Tdeck * source, Tdeck * target[], int targetcount);
int main() {
int e = 0;
char cardstring[100];
Tdeck deck, stackA, stackB, interleaved;
Tdeck * stacks[] = {&stackA, &stackB};
printf("Please input a cardstring: ");
scanf("%s", cardstring);
e |= ReadDeck(&deck, cardstring);
e |= PrintDeck(&deck, "cardstring");
e |= SplitDeckCopy(&deck, stacks, sizeof(stacks) / sizeof(Tdeck*) );
e |= PrintDeck(&stackA, "1st half");
e |= PrintDeck(&stackB, "2nd half");
e |= InterleaveDecksCopy(&interleaved, stacks, sizeof(stacks) / sizeof(Tdeck*) );
e |= PrintDeck(&interleaved, "interleaved");
if( e != 0) printf("There was an error dureing execution.\n");
return e;
}
int ReadDeck(Tdeck * deck, const char *cardstring)
{
int e = 0;
int varCount, n, total = 0;
Tcard card;
memset(deck, 0, sizeof(Tdeck));
do{
n = 0;
varCount = sscanf(&cardstring[total], "%c%i%n", &card.group, &card.number, &n);
total += n;
if( varCount == 2 )
{
//check if card is valid?
e |= DeckAddCopy(deck, &card);
}
else
{
if(strlen(cardstring) != total)
{
//string was not read completely
e |= 1;
}
}
}while(varCount == 2);
return e;
}
int DeckAddCopy(Tdeck * deck, Tcard * card)
{
int e = 0;
if(deck->count >= DECK_MAX)
{
e |= 1;
}
else
{
memcpy(&deck->card[deck->count++], card, sizeof(Tcard));
}
return e;
}
int PrintDeck(Tdeck * deck, const char *deckname)
{
int c;
printf("%s contains %i cards%s", deckname, deck->count, (deck->count == 0)? ".\n":": ");
for(c = 0; c < deck->count; ++c)
{
printf("%c%i%s", deck->card[c].group, deck->card[c].number, ( c+1 < deck->count) ? ", ":".\n");
}
return 0;
}
int InterleaveDecksCopy(Tdeck * target, Tdeck * source[], int sourcecount)
{
int c, s, e = 0;
memset(target, 0, sizeof(Tdeck));
for(c = 0; c < DECK_MAX; ++c)
{
for(s = 0; s < sourcecount ; ++s)
{
if(c < source[s]->count)
{
e |= DeckAddCopy(target, &source[s]->card[c]);
}
}
}
return e;
}
int SplitDeckCopy(Tdeck * source, Tdeck * target[], int targetcount)
{
int c, t, e = 0;
for(t = 0; t < targetcount ; ++t)
{
memset(target[t], 0, sizeof(Tdeck));
}
c = 0;
for(t = 0; t < targetcount ; ++t)
{
int cMax = (source->count) - (((source->count)/targetcount) * targetcount - t - 1 );
for( ; c < (t+1)*(source->count)/targetcount ; ++c)
{
e |= DeckAddCopy(target[t], &source->card[c]);
}
}
return e;
}