idiomatic way to construct the complement of an array in C
I'm writing a function that gets passed a pointer to an array of length 4. This array will contain integers 0 <= x <= 52
and I would like to construct an array of length 48 with every integer from da kine that's not in the passed in array. In python this would be
# just included for specificity
cards = [card for card in deck if card not in hand]
in C the best I can do is
int i, j, k, found_flag;
int cards[48]; /* int hand[4] is passed in */
k = 0;
for (i = 0; i < 52; i+开发者_如何学运维+) {
found_flag = 0;
for (j = 0; j < 4; j++) {
if (i == hand[j]) {
found_flag = 1;
break;
}
}
if (!found_flag) {
cards[k++] = i;
}
}
Is this optimal for this circumstance? Generally, is the 'go-to' pattern?
Sure, your example is fine for a hand size of only 4 - it's clear enough. In situations where the arrays were much larger, then more efficient algorithms based on various kinds of sorting could be used.
For example, a radix sort eliminates the nested loops:
int i, j;
int card_in_hand[52] = { 0 };
int cards[48]; /* int hand[4] is passed in */
for (i = 0; i < 4; i++)
card_in_hand[hand[i]] = 1;
j = 0;
for (i = 0; i < 52; i++)
if (!card_in_hand[i])
cards[j++] = i;
Could this be done this way?
cards_in_deck[48]={1};
for (int i=0;i<4;i++)
cards_in_deck[hand[i]]=0;
The cards_in_deck is an array with value of 1 for those that are not in the deck. Is this what you are looking for ?
Here's the little test program I put together to solve this one. It creates a set to show which cards are selected and scans through the set to build the array of the cards that are left.
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
int cardsSelected[4] = {3,7,10,49} ;
int cardsLeft[48] ;
int allCards[52] ;
memset(allCards,0,sizeof(int)*52) ;
for(int i= 0; i < 4; ++i) {
allCards[cardsSelected[i]] = 1 ;
}
int k = 0 ;
for(int i =0; i < 52; ++i) {
if (!allCards[i])
cardsLeft[k++] = i ;
}
for(int i = 0; i < 48; ++i) {
printf("%d ", cardsLeft[i]) ;
}
printf("\n") ;
return 0;
}
In C, iterate over the sorted cards in hand:
int cards_in_deck[48];
const int ranges[6][2] = {
{0, hand[0]},
{hand[0] + 1, hand[1]},
{hand[1] + 1, hand[2]},
{hand[2] + 1, hand[3]},
{hand[3] + 1, hand[4]},
{hand[4] + 1, 52}
};
int j = 0;
for (int i = 0; i < sizeof(ranges)/sizeof(ranges[0]); i++) {
const int *range = ranges[i];
for (int k = range[0]; k < range[1]; k++)
cards_in_deck[j++] = k;
}
In python the code looks like this:
hand = [0, 10, 11, 40, 51]
ranges = [
[0, hand[0]],
[hand[0] + 1, hand[1]],
[hand[1] + 1, hand[2]],
[hand[2] + 1, hand[3]],
[hand[3] + 1, hand[4]],
[hand[4] + 1, 52]
]
cards_in_deck = [k for r in ranges for k in range(r[0], r[1])]
精彩评论