C 中的转换是如何工作的?
How casting works in C?
我在 leetcode 上解决了一个 problem,这是我的代码。
/*
max int 2147483647 (10^10)
max uint 4294967295 (10^10)
ULONG_MAX 18446744073709551615 (10^20)
LONG_MAX 9223372036854775807 (10^20)
USHRT_MAX 65535, SHRT_MAX 32767
*/
#include <stdio.h>
#include <math.h>
int main(void) {
int t;
scanf("%d", &t);
while (t--) {
int length;
scanf("%d", &length);
char string[length];
scanf("%s", string);
long int answer = 0;
int ones = 0;
for (int i = 0; i < length; i++) {
ones = ones + (string[i] == '1') * (i + 1);
if (ones & 1) {
answer = (answer + (long int)pow(2, length - (i + 1))) % 998244353;
}
}
printf("%ld\n", answer);
}
return 0;
}
它适用于较小的值(可能是 int 可以容纳的值)。但是在计算大值时却给出了意想不到的结果
然后我认为这可能是由于溢出造成的,所以我将变量 int answer
更改为 long int answer
我认为这会解决问题,但它没有,而且甚至破坏了代码较小的值
然后我注意到我正在使用 pow
函数,它肯定会超过高长度值的限制,因为 pow
在 return 中给出双倍值,我正在转换它之前有 (int)pow(2, length - (i+1))
的 int
,我改为 (long int)pow(2, length - (i+1))
我正在传递这些值来测试代码。
4
16
1111010010111101
2
10
6
101101
4
1111
预期结果是
49359
3
48
12
但是我得到了
49359
65535
49152
49152
我在使用 int answer
和 (int)pow(...)
时得到了预期的结果,但是如果我将 answer 或 pow 转换为 long,我会得到意想不到的结果。我不确定这是由于转换还是其他原因造成的,但据我所知,只有当我将这些变量转换为 long 时才会发生这种情况。
代码中存在多个问题:
如果输入的 t
值为负数,while (t--)
将导致意外行为。使用 while (t-- > 0)
char string[length];
没有足够的 space 用于 length
个字符和空终止符。使用 char string[length + 1];
scanf("%s", string);
不提供任何防止缓冲区溢出的保护。没有简单的方法可以告诉 scanf()
为 %s
读取最多可变数量的字节。由于长度可以与 100000
一样大,您可能应该从堆中分配数组并使用 getchar()
.
读取位
循环中的代码似乎没有实现问题的解决方案:
Given a binary string S
, she defines the beauty of the string as the bitwise XOR of decimal representations of all substrings of S
.
这些说明具有误导性,因为结果与任何东西的十进制表示法都无关。但是您的代码不会转换所有子字符串,只应显示结果模 998244353
。对模块应用 xor 会产生不同的结果。
此外,pow
无需转换二进制表示:您可以将 res
乘以 2,然后在循环中添加下一个数字的值。
要计算生成的位串,请考虑偏移量 i
处的位,从字符串的开头开始,偏移量为 0
:
对于仅删除前缀的子字符串,它将与自身进行 i
次异或运算。
然后索引 j
小于 i
的每个位将对每个子字符串进行异或 j
次,最后 i-j
位被删除.
如果 i
是奇数,XORing i
次将产生 0
,因此与使用 [= 最后一位相反的掩码具有相同的效果28=].
您可以为此使用 2 个嵌套循环:
for (int i = 0; i < length; i++) {
int bit = (string[i] - '0') & ~i;
for (j = 0; j < i; j++) {
bit ^= (string[j] - '0') & ~j;
}
answer = (answer * 2 + bit) % 998244353;
}
这是修改后的版本:
#include <stdio.h>
#include <stdlib.h>
int main() {
int t, i, j, c;
int string_size = 0;
unsigned char *string = NULL; /* array for the bits */
/* read the number of test cases */
if (scanf("%d", &t) != 1)
return 1;
while (t-- > 0) {
int length;
/* read the length */
if (scanf("%d", &length) != 1)
return 1;
/* discard the rest of the input line */
while ((c = getchar()) != EOF && c != '\n')
continue;
/* reallocate the string if required */
if (length > string_size) {
string_size = length;
string = realloc(string, string_size);
if (string == NULL)
return 1;
}
/* read the bits */
i = 0;
while (i < length && ((c = getchar()) == '0' || c == '1')) {
string[i++] = (unsigned char)(c - '0');
}
/* discard the rest of the input line */
while (c != EOF && c != '\n') {
c = getchar();
}
/* compute the answer one bit at a time */
long int answer = 0;
for (i = 0; i < length; i++) {
/* compute the next bit of the result string */
int bit = string[i] & ~i;
for (j = 0; j < i; j++) {
bit ^= string[j] & ~j;
}
/* compute the answer one bit at a time, reducing modulo 998244353 */
answer = (answer * 2 + bit) % 998244353;
}
printf("%ld\n", answer);
}
free(string);
return 0;
}
我在 leetcode 上解决了一个 problem,这是我的代码。
/*
max int 2147483647 (10^10)
max uint 4294967295 (10^10)
ULONG_MAX 18446744073709551615 (10^20)
LONG_MAX 9223372036854775807 (10^20)
USHRT_MAX 65535, SHRT_MAX 32767
*/
#include <stdio.h>
#include <math.h>
int main(void) {
int t;
scanf("%d", &t);
while (t--) {
int length;
scanf("%d", &length);
char string[length];
scanf("%s", string);
long int answer = 0;
int ones = 0;
for (int i = 0; i < length; i++) {
ones = ones + (string[i] == '1') * (i + 1);
if (ones & 1) {
answer = (answer + (long int)pow(2, length - (i + 1))) % 998244353;
}
}
printf("%ld\n", answer);
}
return 0;
}
它适用于较小的值(可能是 int 可以容纳的值)。但是在计算大值时却给出了意想不到的结果
然后我认为这可能是由于溢出造成的,所以我将变量 int answer
更改为 long int answer
我认为这会解决问题,但它没有,而且甚至破坏了代码较小的值
然后我注意到我正在使用 pow
函数,它肯定会超过高长度值的限制,因为 pow
在 return 中给出双倍值,我正在转换它之前有 (int)pow(2, length - (i+1))
的 int
,我改为 (long int)pow(2, length - (i+1))
我正在传递这些值来测试代码。
4
16
1111010010111101
2
10
6
101101
4
1111
预期结果是
49359
3
48
12
但是我得到了
49359
65535
49152
49152
我在使用 int answer
和 (int)pow(...)
时得到了预期的结果,但是如果我将 answer 或 pow 转换为 long,我会得到意想不到的结果。我不确定这是由于转换还是其他原因造成的,但据我所知,只有当我将这些变量转换为 long 时才会发生这种情况。
代码中存在多个问题:
-
如果输入的
while (t--)
将导致意外行为。使用while (t-- > 0)
char string[length];
没有足够的 space 用于length
个字符和空终止符。使用char string[length + 1];
读取位scanf("%s", string);
不提供任何防止缓冲区溢出的保护。没有简单的方法可以告诉scanf()
为%s
读取最多可变数量的字节。由于长度可以与100000
一样大,您可能应该从堆中分配数组并使用getchar()
.循环中的代码似乎没有实现问题的解决方案:
Given a binary string
S
, she defines the beauty of the string as the bitwise XOR of decimal representations of all substrings ofS
.这些说明具有误导性,因为结果与任何东西的十进制表示法都无关。但是您的代码不会转换所有子字符串,只应显示结果模
998244353
。对模块应用 xor 会产生不同的结果。此外,
pow
无需转换二进制表示:您可以将res
乘以 2,然后在循环中添加下一个数字的值。
t
值为负数,要计算生成的位串,请考虑偏移量 i
处的位,从字符串的开头开始,偏移量为 0
:
对于仅删除前缀的子字符串,它将与自身进行
i
次异或运算。然后索引
j
小于i
的每个位将对每个子字符串进行异或j
次,最后i-j
位被删除.
如果 XORing
i
次将产生0
,因此与使用 [= 最后一位相反的掩码具有相同的效果28=].您可以为此使用 2 个嵌套循环:
for (int i = 0; i < length; i++) { int bit = (string[i] - '0') & ~i; for (j = 0; j < i; j++) { bit ^= (string[j] - '0') & ~j; } answer = (answer * 2 + bit) % 998244353; }
i
是奇数,这是修改后的版本:
#include <stdio.h>
#include <stdlib.h>
int main() {
int t, i, j, c;
int string_size = 0;
unsigned char *string = NULL; /* array for the bits */
/* read the number of test cases */
if (scanf("%d", &t) != 1)
return 1;
while (t-- > 0) {
int length;
/* read the length */
if (scanf("%d", &length) != 1)
return 1;
/* discard the rest of the input line */
while ((c = getchar()) != EOF && c != '\n')
continue;
/* reallocate the string if required */
if (length > string_size) {
string_size = length;
string = realloc(string, string_size);
if (string == NULL)
return 1;
}
/* read the bits */
i = 0;
while (i < length && ((c = getchar()) == '0' || c == '1')) {
string[i++] = (unsigned char)(c - '0');
}
/* discard the rest of the input line */
while (c != EOF && c != '\n') {
c = getchar();
}
/* compute the answer one bit at a time */
long int answer = 0;
for (i = 0; i < length; i++) {
/* compute the next bit of the result string */
int bit = string[i] & ~i;
for (j = 0; j < i; j++) {
bit ^= string[j] & ~j;
}
/* compute the answer one bit at a time, reducing modulo 998244353 */
answer = (answer * 2 + bit) % 998244353;
}
printf("%ld\n", answer);
}
free(string);
return 0;
}