这只是我的第二个编程课程。有30个房间,我们必须看到每个房间里的东西,并计算它。我已经使用for循环来通过30个房间,我知道我必须使用一个计数器来查看每个房间里的东西。我不知道如何计算单词中的位数。下面是示例输入/输出以及我目前在代码中的内容。
示例输入:
9 23 @Z
如果密钥是:
0 gold_bar
1 silver_bar
2 diamond
3 copper_ring
4 jumpy_troll
5 air
6 angry_troll
7 plutonium_troll
线路是9 23 @Z然后房间在9,23(字符Z与二进制:01011010)有第1,3,4,6项.silver_bar,copper_ring,jumpy_troll,angry_troll
#include <stdio.h>
#include <stdlib.h>
int main()
{
// contains x and y coordinate
int first, second;
char third[100];
char Map[30][30];
// map initialization
for(int x=0; x<30; x++){
for(int y=0; y<30; y++){
Map[x][y] = '.';
}
}
while(scanf("%d %d %s",&first, &second, third) != -1) {
// Condition 1: a zero coordinate
if (first==0 || second==0) exit(0);
// Condition 2: coordinate out of range
if (first<0 || first>30 || second<0 || second>30){
printf("Error: out of range 0-30!\n");
exit(1);
}
// bit counter
for( int bit_p=0; bit_p<8; bit_p++){
}
Map[second-1][first-1] = third[1];
return 0;
}
示例输入:
1 20 @@
2 21 @A
3 22 @#
4 23 @1
5 22 @@
6 22 @@
7 22 @@
8 22 @@
9 23 @Z Here be trolls � not!
10 23 @+
12 23 @@
13 24 @@
11 22 @@
14 22 @2
15 21 @1
16 20 @@
17 19 @@
18 20 @@
19 19 @@
20 18 @@
21 17 @*
22 16 @*
23 15 @%
0 14 @7
0 gold_bar
1 silver_bar
2 diamond
3 copper_ring
4 jumpy_troll
5 air
6 angry_troll
7 plutonium_troll
示例输出:
6 gold_bar
6 silver_bar
1 diamond
4 copper_ring
4 jumpy_troll
8 air
15 angry_troll
0 plutonium_troll
答案 0 :(得分:4)
单词的各个位不能用C直接访问,所以我们必须做其他事情才能得到它们。
考虑你的值,它给出了哪个位:
0 gold_bar 00000001B or 0x01
1 silver_bar 00000010B or 0x02
2 diamond 00000100B or 0x04
3 copper_ring 00001000B or 0x08
4 jumpy_troll 00010000B or 0x10
5 air 00100000B or 0x20
6 angry_troll 01000000B or 0x40
7 plutonium_troll 10000000B or 0x80
因此,通过观察,我们可以考虑如果我们有以下内容会发生什么:
unsigned char test = 'z'
unsigned char res = test & 0x02
现在正如你所说,'z'的二进制表示为01111010,如果我们做了逻辑,我们有2:
z: 01111010B
0x02: 00000010B
----------
00000010B
所以表达测试&amp; 0x02的计算结果为0x02。那么,我们怎么能用呢?我们可以这样写:
if((test & 0x02) == 0x02)
++cntSilverBars;
扩展这个,假设我们有适当定义的变量(即 cntAuBars将被声明为int cntAuBars并保留发现的金条数量:
if((test & 0x01) == 0x01)
++cntAuBars;
if((test & 0x02) == 0x02)
++cntAgBars;
if((test & 0x04) == 0x04)
++cntDiamonds;
if((test & 0x08) == 0x08)
++cntCuRings;
if((test & 0x10) == 0x10)
++cntJumpyTroll;
if((test & 0x20) == 0x20)
++cntSilverBars;
if((test & 0x40) == 0x40)
++cntAir;
if((test & 0x80) == 0x80)
++cntPuTroll;
虽然上述方法有效,但可以重写为:
int itemCnt[8] = {0}; // array to hold count of items, index is item type
unsigned char test; // holds contents of room.
int loc;
for(loc = 0; loc < 8; loc++) // loop over every bit and see if it is set
{
unsigned char bitPos = 1 << loc; // generate a bit-mask
if((test & bitPos) == bitPos)
++itemCnt[loc];
}
例如,以下程序:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
unsigned char test = 'z';
int items[8] = {0};
int loc;
int ndx;
for(loc = 0; loc < 8; loc++)
{
unsigned bitPos = 1 << loc;
if((test & bitPos) == bitPos)
++items[loc];
}
for(ndx = 0; ndx < 8; ndx++)
{
printf("%d, ", items[ndx]);
}
return 0;
}
可以编译为:gcc -g -ansi -pedantic -Wall temp.c -o temp
,并且在运行时生成以下数组(在调试器中查看时):
(gdb) print /t 'z'
$7 = 1111010
(gdb) print items
$8 = {0, 1, 0, 1, 1, 1, 1, 0}
答案 1 :(得分:1)
此代码检查一个字符,如果该位置的位为0则填充值为0的8个整数的数组,如果该位置的位为1,则填充值为1
char c = 'Z';
int bits[8];
int n;
char aux = c;
for ( n=0; n<8; ++n ) {
if ( aux & '\1' )
bits[n] = 1;
else
bits[n] = 0;
aux = aux >> 1;
}
我听说过 aux & '\1'
和aux = aux >> 1
代码。
'\ 1'是ASCII代码1的字符,因此它在位置0的位是1而所有其他位都是0.当我们对一个字符进行'\ 1'的按位AND时我们得到1如果该字符是1位于位0,否则我们得到0。
aux = aux >> 1
将位向左移位一位,以便在下一个操作中位置0的位将是最初位于位置1的位。
答案 2 :(得分:0)
没有用于累积单词中的位计数的内置函数。对于每个房间,您需要检查每个8位,如果设置了该位,则递增适当的计数变量。有很多方法可以做到这一点,但特别是对于想要尽可能清楚地完成它的课程。
基本思想是你想要将你读到的单词(框架中的“第三个”)与一个位掩码进行比较,该位掩码移位到你正在测试的位位置。通过使用if语句对掩码和输入进行比较并对其进行测试。我已经将一个示例放入您的框架中了:
// bit counter
for( int bit_p=0; bit_p<8; bit_p++){
if (third & (1 << bit_p))
tally[bit_p]++;
}
常见的部分是结构if (input & MASK) {do_whatever}
。一旦了解了该结构的工作原理,就可以将其应用于许多情况。