如何在 C# 中翻转位?
How to flip bits in C#?
我有一个字符串形式的二进制数作为
string input = "10110101101";
现在我需要翻转(0 to 1
和 1 to 0
)它的 前 3 位。
结果输出将是 01010101101
如何在 C# 中执行此操作?
解决方法很简单;只需将值与 1 进行异或(0 也可以)。
步数:
- 对于前 x 个字符,与 1 进行异或并得到 return 值(简单的 for 循环)。
- 用新字符串替换旧字符串。
从字符串中提取 StringBuilder
,翻转前三个字符,然后将 StringBuilder
转换回 string
:
var sb = new StringBuilder(input);
Debug.Assert(sb.Length >= 3);
for (int i = 0 ; i != 3 ; i++) {
sb[i] = sb[i] == '0' ? '1' : '0';
}
var res = sb.ToString();
有多种 "smart" 方法可以无条件地翻转字符,但考虑到数字在一个 string
中,让翻转更智能不会给你带来太多 CPU 循环.
这个有效:
string input = "10110101101";
string output =
new string(
input
.Take(3)
.Select(c => c == '0' ? '1' : '0')
.Concat(input.Skip(3))
.ToArray());
它给出了结果:
01010101101
另一种方法是这样做:
string input = "10110101101";
string flips = "11100000000";
int value = Convert.ToInt32(input, 2) ^ Convert.ToInt32(flips, 2);
string output = Convert.ToString(value, 2).PadLeft(input.Length, '0');
假设给定一个大小为 N
的数组 a。数组的元素是 a[0], a[1], ... a[N - 1]
,其中每个 a 是 0
或 1
。您可以对数组执行一种转换:选择任意两个整数 L
和 R
,然后翻转第 L 位和第 R 位之间(包括在内)的所有元素。换句话说,L 和 R 代表 left-most 和 right-most 索引,它们划分了您将决定翻转其位的段的边界。 ('Flipping' 有点意思,0
转换为 1
,1
转换为 0
。)
你在最后的bit-string中最多可以获得多少个'1'位(用S表示)?
输入格式:
第一行有一个整数N
接下来的 N
行包含数组中的 N
个元素,a[0], a[1], ... a[N - 1]
,每行一个。
例如考虑
1 ≤ N ≤ 100,000.
d can be either 0 or 1. It cannot be any other integer.
0 ≤ L ≤ R < N
Sample Input:
810010010
Sample Output:
6
Explanation:
We can get a maximum of 6 ones in the given binary array by performing either of the following operations:
Flip [1, 5] ⇒ 1 1 1 0 1 1 1 0
or
Flip [1, 7] ⇒ 1 1 1 0 1 1 0 1
解法:
bits 数组将只包含 0 和 1。所以我们可以将 0 视为 -1,那么任务就是找到
subArray 的最小总和(以位为单位),它是具有最大值的 subArray
(0 的数量- 1 的数量)。
我们可以使用与查找最大和子数组相同的方法来查找最小和子数组。在那之前,
我们需要先遍历位来得到原来的 1 的个数。假设最小总和为 minRes 并且
1s的原始数量是currentOne。那么minRes应该是负数,所以returncurrentOne-minRes。
边缘案例:
所有边缘情况都可以使用上述方法处理。如果所有元素都是 0,那么我们将所有 -1 加在一起。
如果所有元素都是 1,那么 minRes 应该是 0,这意味着我们不翻转任何位。
时间:O(n)Space:O(1)
using System;
using System.Linq;
public class Test
{
public static int FlippingBits(int[] bits){
int currentOne = 0; //original number of 1s in bits
foreach(int i in bits){
if(i==1)
currentOne++;
}
int minRes = MinSubArray(bits); //minRes is negative number
return currentOne-minRes;
}
//find the min sum of subArray in bits
private static int MinSubArray(int[] bits){
int minRes = 0, minHere=0;
foreach(int i in bits){
if(i==0)
minHere-=1;
else
minHere+=1;
minHere = Math.Min(minHere,0); //keep minHere<=0
minRes = Math.Min(minHere, minRes);
}
return minRes; //-minRes is the number of 1 can be added to the array after flipping
}
public static void Main()
{
int num = int.Parse(Console.ReadLine());
for(int i=0;i<num;i++){
string[] input = Console.ReadLine().Split();
int[] bits = input.Select(y=>int.Parse(y)).ToArray();
Console.WriteLine(FlippingBits(bits));
}
}
}
使用 Convert.ToInt32
、Convert.ToString
(否则未知且未使用)和 bitwise-XOR
的替代方法
string input = "10110101101";
int flipNo = 3;
int output = Convert.ToInt32(input, 2);
for (int i = input.Length - 1; i >= input.Length - flipNo; --i)
output ^= 1 << i;
只需使用output
,或者如果你想在string
中显示output
,你可以这样做:
string display = Convert.ToString(output, 2).PadLeft(input.Length, '0');
我有一个字符串形式的二进制数作为
string input = "10110101101";
现在我需要翻转(0 to 1
和 1 to 0
)它的 前 3 位。
结果输出将是 01010101101
如何在 C# 中执行此操作?
解决方法很简单;只需将值与 1 进行异或(0 也可以)。
步数:
- 对于前 x 个字符,与 1 进行异或并得到 return 值(简单的 for 循环)。
- 用新字符串替换旧字符串。
从字符串中提取 StringBuilder
,翻转前三个字符,然后将 StringBuilder
转换回 string
:
var sb = new StringBuilder(input);
Debug.Assert(sb.Length >= 3);
for (int i = 0 ; i != 3 ; i++) {
sb[i] = sb[i] == '0' ? '1' : '0';
}
var res = sb.ToString();
有多种 "smart" 方法可以无条件地翻转字符,但考虑到数字在一个 string
中,让翻转更智能不会给你带来太多 CPU 循环.
这个有效:
string input = "10110101101";
string output =
new string(
input
.Take(3)
.Select(c => c == '0' ? '1' : '0')
.Concat(input.Skip(3))
.ToArray());
它给出了结果:
01010101101
另一种方法是这样做:
string input = "10110101101";
string flips = "11100000000";
int value = Convert.ToInt32(input, 2) ^ Convert.ToInt32(flips, 2);
string output = Convert.ToString(value, 2).PadLeft(input.Length, '0');
假设给定一个大小为 N
的数组 a。数组的元素是 a[0], a[1], ... a[N - 1]
,其中每个 a 是 0
或 1
。您可以对数组执行一种转换:选择任意两个整数 L
和 R
,然后翻转第 L 位和第 R 位之间(包括在内)的所有元素。换句话说,L 和 R 代表 left-most 和 right-most 索引,它们划分了您将决定翻转其位的段的边界。 ('Flipping' 有点意思,0
转换为 1
,1
转换为 0
。)
你在最后的bit-string中最多可以获得多少个'1'位(用S表示)?
输入格式:
第一行有一个整数N
接下来的 N
行包含数组中的 N
个元素,a[0], a[1], ... a[N - 1]
,每行一个。
例如考虑
1 ≤ N ≤ 100,000.
d can be either 0 or 1. It cannot be any other integer.
0 ≤ L ≤ R < N
Sample Input:
810010010
Sample Output:
6
Explanation:
We can get a maximum of 6 ones in the given binary array by performing either of the following operations:
Flip [1, 5] ⇒ 1 1 1 0 1 1 1 0
or
Flip [1, 7] ⇒ 1 1 1 0 1 1 0 1
解法: bits 数组将只包含 0 和 1。所以我们可以将 0 视为 -1,那么任务就是找到 subArray 的最小总和(以位为单位),它是具有最大值的 subArray (0 的数量- 1 的数量)。 我们可以使用与查找最大和子数组相同的方法来查找最小和子数组。在那之前, 我们需要先遍历位来得到原来的 1 的个数。假设最小总和为 minRes 并且 1s的原始数量是currentOne。那么minRes应该是负数,所以returncurrentOne-minRes。 边缘案例: 所有边缘情况都可以使用上述方法处理。如果所有元素都是 0,那么我们将所有 -1 加在一起。 如果所有元素都是 1,那么 minRes 应该是 0,这意味着我们不翻转任何位。 时间:O(n)Space:O(1)
using System;
using System.Linq;
public class Test
{
public static int FlippingBits(int[] bits){
int currentOne = 0; //original number of 1s in bits
foreach(int i in bits){
if(i==1)
currentOne++;
}
int minRes = MinSubArray(bits); //minRes is negative number
return currentOne-minRes;
}
//find the min sum of subArray in bits
private static int MinSubArray(int[] bits){
int minRes = 0, minHere=0;
foreach(int i in bits){
if(i==0)
minHere-=1;
else
minHere+=1;
minHere = Math.Min(minHere,0); //keep minHere<=0
minRes = Math.Min(minHere, minRes);
}
return minRes; //-minRes is the number of 1 can be added to the array after flipping
}
public static void Main()
{
int num = int.Parse(Console.ReadLine());
for(int i=0;i<num;i++){
string[] input = Console.ReadLine().Split();
int[] bits = input.Select(y=>int.Parse(y)).ToArray();
Console.WriteLine(FlippingBits(bits));
}
}
}
使用 Convert.ToInt32
、Convert.ToString
(否则未知且未使用)和 bitwise-XOR
string input = "10110101101";
int flipNo = 3;
int output = Convert.ToInt32(input, 2);
for (int i = input.Length - 1; i >= input.Length - flipNo; --i)
output ^= 1 << i;
只需使用output
,或者如果你想在string
中显示output
,你可以这样做:
string display = Convert.ToString(output, 2).PadLeft(input.Length, '0');