异或的应用场景:以O(N)时间复杂度查找文章中出现了奇数次的字符串
有个500g大小的文件,程序的运行内存1g,这个文件里边每行一个单词。
正常情况下,每个单词出现的次数为偶数次;
但是,由于程序出现bug,有一个单词出现了奇数次,怎么找到这个单词?
import com.google.common.base.Splitter; import org.apache.commons.lang.RandomStringUtils; import java.util.List; /** * Created by kongzheng on 16/3/31. */ public class Finder { public static void main(String[] args) throws Exception { final String SEEDS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; StringBuilder buf = new StringBuilder(); for (int i = 0; i < 100000; i++) { String eventStr = "A" + RandomStringUtils.random(19, SEEDS); buf.append(eventStr).append(" "); buf.append(eventStr).append(" "); } String oddStr = "B" + RandomStringUtils.random(19, SEEDS); System.out.println(oddStr); buf.append(oddStr).append(" "); List<String> list = Splitter.on(' ').omitEmptyStrings().trimResults().splitToList(buf.toString()); byte[] array0 = list.get(0).getBytes(); for (int i = 1; i < list.size(); i++) { byte[] arrayi = list.get(i).getBytes(); array0 = xor(array0, arrayi); } System.out.println(new String(array0)); } private static byte[] xor(byte[] array1, byte[] array2) { byte[] buf = new byte[Math.max(array1.length, array2.length)]; for (int i = 0; i < buf.length; i++) { byte b1 = i < array1.length ? array1[i] : 0; byte b2 = i < array2.length ? array2[i] : 0; buf[i] = (byte) (b1 ^ b2); } return buf; } }
这种方法,时间复杂度是O(N),空间复杂度是O(1)。
关于异或的扩展阅读: 感受异或的神奇