Java异或操作

Java异或操作,java,algorithm,bit-manipulation,xor,bitwise-xor,Java,Algorithm,Bit Manipulation,Xor,Bitwise Xor,我遇到了一个问题,所有的程序都只给出了一条逻辑。在以下问题的缺失行中可以填写什么 问题陈述 杰克和丹尼尔是朋友。 他们想加密他们的对话,这样他们就可以避免被侦探机构截获。于是他们发明了一种新密码。 每个消息都被编码为长度为N的二进制表示B。 然后写下K次,移动0,1,…,K−1位。 如果B=1001010,K=4,则看起来像: 1001010 1001010 1001010 1001010 然后计算每列中的XOR并记下。该数字称为S。例如,对上述示例中的数字进行异或运算将导致 11

我遇到了一个问题,所有的程序都只给出了一条逻辑。在以下问题的缺失行中可以填写什么

问题陈述 杰克和丹尼尔是朋友。 他们想加密他们的对话,这样他们就可以避免被侦探机构截获。于是他们发明了一种新密码。 每个消息都被编码为长度为N的二进制表示B。 然后写下K次,移动0,1,…,K−1位。 如果B=1001010,K=4,则看起来像:

1001010
 1001010
  1001010
   1001010
然后计算每列中的XOR并记下。该数字称为S。例如,对上述示例中的数字进行异或运算将导致

1110100110
然后,编码信息S和K被发送给Daniel

杰克正在使用这种编码算法,并要求丹尼尔实现一种解码算法。你能帮丹尼尔实现这个吗

输入格式
  • 第一行包含两个整数N和K
  • 第二行包含长度为N+K的字符串S−1由1和0组成
输出格式 长度为N的解码消息,由1和0组成

约束条件
  • 一,≤N≤10^6
  • 一,≤K≤10^6
  • |S |=N+K−一,
  • 保证S是正确的
样本输入#00 样本输出#00 样本输入#01 样本输出#01 输入说明#00 输入解释#01
import java.io.*;
公共类解决方案{
公共静态void solve(输入,打印输出)引发IOException{
int n=in.nextInt();
int k=in.nextInt();
char[]c=in.next().toCharArray();
int x=0;
char[]ans=新字符[n];
对于(int i=0;i=k-1){
****把缺的一行填在这里****
}
}
out.println(ans);
}
公共静态void main(字符串[]args)引发IOException{
PrintWriter out=新的PrintWriter(System.out);
求解(新输入(新BufferedReader(新InputStreamReader(System.in))),输出;
out.close();
}
静态类输入{
缓冲读取器;
StringBuilder sb=新的StringBuilder();
公共输入(BufferedReader in){
this.in=in;
}
公共输入(字符串s){
this.in=新的BufferedReader(新的StringReader);
}
公共字符串next()引发IOException{
sb.设定长度(0);
while(true){
int c=in.read();
如果(c==-1){
返回null;
}
如果(“\n\r\t”.indexOf(c)=-1){
sb.附加((char)c);
打破
}
}
while(true){
int c=in.read();
if(c==-1 | |“\n\r\t”.indexOf(c)!=-1){
打破
}
sb.附加((char)c);
}
使某人返回字符串();
}
public int nextInt()引发IOException{
返回整数.parseInt(next());
}
public long nextLong()引发IOException{
返回Long.parseLong(next());
}
public double nextDouble()引发IOException{
返回Double.parseDouble(next());
}
}
}
注意:请阅读解释,简单地通过复制粘贴答案来解决问题是没有用的

您可以利用的约束是

第一位不受加密算法的影响

事实上,因为所有的“面具”都至少向右移动了一个。因此,您可以假设加密部分的第一位也是解密内容的第一位

既然您知道了第一位,就可以轻松地重构第二位,因为它只与我们已经知道的第一位进行异或运算。所以我们可以计算第二个

第三位与第一位和第二位进行异或运算,因此基本上要做的是保持一个值,该值是所有已获得值的异或,并将其与下一个值进行异或运算。初始值为零

示例

获取第一个示例输入:

1110100110
我们可以推导出第一位是a
1
。现在我们知道第二位的掩码的形式是:

       1110100110
mask    1????????
result 10
现在我们知道第三位的掩码是
1
0
的异或,因此
1

       1110100110
mask    11???????
result 100
反复地,这最终将导致:

index      0123456789       
data       1110100110
submasks    1001010
             1001010
              1001010
mask       0111??????
result     1001??????
现在,在
k-1
迭代之后,一个人不再有额外的子掩码,事实上:一个人只写
k
乘以数据一的结果,而
k-1
乘以子掩码。因此,现在我们不再对新数据进行异或运算:我们只对结果的最后
k
位进行异或运算,这可以通过对结果
k
左侧位置的位进行异或运算(或简单地进行异或运算)来完成

对于下一个掩码,我们用结果的最后一位(
1
)和结果的第一位(
1
)对状态(掩码的最后一位)进行异或运算,这意味着状态保持不变(
1
):

现在我们对最后一个结果位(
0
)和第二个结果位(
0
)进行异或运算:

对于下一个,我们对最后一个(
1
)和第三个(
0
)进行异或,从而交换状态。通过继续执行此过程,我们最终以:

index      0123456789
data       1110100110
submasks    1001010
             1001010
              1001010
mask       0111110???
result     1001010???
现在我们对剩下的位不再感兴趣,所以我们终止

必须修改什么?

if
-部分中,我们需要使用
i-(k-1)
-th进行异或(
^
101111
 101111
-------
1110001 
import java.io.*;

public class Solution {

    public static void solve(Input in, PrintWriter out) throws IOException {
        int n = in.nextInt();
        int k = in.nextInt();
        char[] c = in.next().toCharArray();
        int x = 0;
        char[] ans = new char[n];
        for (int i = 0; i < n; ++i) {
            ans[i] = (char) (((c[i] - '0') ^ x) + '0');// I understand we are converting the character into integer (c[i] - '0') then xoring it with x which is holding 0 and then again adding '0' to convert back it into character.
            x ^= ans[i] - '0';// But why are we doing this!!. From this line onward things are not clear.
            if (i >= k - 1) {
                ****FILL THE MISSING LINE HERE****

            }
        }
        out.println(ans);
    }

    public static void main(String[] args) throws IOException {
        PrintWriter out = new PrintWriter(System.out);
        solve(new Input(new BufferedReader(new InputStreamReader(System.in))), out);
        out.close();
    }

    static class Input {
        BufferedReader in;
        StringBuilder sb = new StringBuilder();

        public Input(BufferedReader in) {
            this.in = in;
        }

        public Input(String s) {
            this.in = new BufferedReader(new StringReader(s));
        }

        public String next() throws IOException {
            sb.setLength(0);
            while (true) {
                int c = in.read();
                if (c == -1) {
                    return null;
                }
                if (" \n\r\t".indexOf(c) == -1) {
                    sb.append((char)c);
                    break;
                }
            }
            while (true) {
                int c = in.read();
                if (c == -1 || " \n\r\t".indexOf(c) != -1) {
                    break;
                }
                sb.append((char)c);
            }
            return sb.toString();
        }

        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }

        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }

        public double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }
    }
}
1110100110
       1110100110
mask    1????????
result 10
       1110100110
mask    11???????
result 100
index      0123456789       
data       1110100110
submasks    1001010
             1001010
              1001010
mask       0111??????
result     1001??????
index      0123456789
data       1110100110
submasks    1001010
             1001010
              1001010
mask       01111?????
result     10010?????
index      0123456789
data       1110100110
submasks    1001010
             1001010
              1001010
mask       011111????
result     100101????
index      0123456789
data       1110100110
submasks    1001010
             1001010
              1001010
mask       0111110???
result     1001010???
if (i >= k - 1) {
    x ^= ans[i-(k-1)] - '0';
}