#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <fstream>
using namespace std;
#define CRC32_POLY 0x82F63B78
void crc32( int *, const string &);
void crc32( int *, const char *, unsigned int);
void deldup(const string &, bool output=true);
int main(int argc, char *argv[]) {
if(argc<2) return 0;
remove("duplicate.txt");
string s=argv[1];
if( s!="/d" && s!="/D" ) {
for(int n=1; n<argc; n++) deldup(argv[n]);
return 0; }
// argv[2]からそれ以降を取り除く
for(int n=3; n<argc; n++) deldup(argv[n], false);
deldup(argv[2]);
return 0; }
void deldup(const string & path, bool output) {
static vector< set< int> > M(256);
static ofstream fo;
string buf, str;
char c[5]; int n, x; unsigned char l;
ifstream ifs(path);
while (getline(ifs, str)) {
if(str.empty()) continue;
n = str.length()-1;
if(str[n] =='\r' || str[n] =='\n') {
str.resize(n);
if(str.empty()) continue; }
crc32( (int*)c, str);
c[4] = (char)(str.length() & 0xFF);
l = *(unsigned char*)c;
x = *(int*)&c[1];
if(M[l].find(x) != M[l].end()) {
if(!output) continue;
if(!fo.is_open()) fo.open("duplicate.txt");
fo<<str+"\n";
continue; }
M[l].insert(x);
if(!output) continue;
buf += str + "\n";
if(buf.length()<100*1024) continue;
cout<<buf;
buf=""; }
if(output) cout<<buf; }
void crc32(int *x, const std::string &p) { crc32( x, &p[0], p.size() ); }
void crc32( int *x, const char *p , unsigned int length){
static int init = 0;
static int crcT[256];
if(!init) {
init=1;
for (int i=0; i<256; i++) {
int z = i;
for (int j=8; j>0; j--)
if(z&1) z=(z>>1)^CRC32_POLY; else z>>=1;
crcT[i]=z; }}
*x = 0xFFFFFFFF;
for (unsigned int i = 0; i < length; i++)
*x = ((*x >> 8) & 0x00FFFFFF) ^ crcT[(*x ^ p[i]) & 0xFF ];
*x ^= 0xFFFFFFFF; }
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8c2V0PgojaW5jbHVkZSA8ZnN0cmVhbT4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKI2RlZmluZSBDUkMzMl9QT0xZIDB4ODJGNjNCNzgKCnZvaWQgY3JjMzIoIGludCAqLCBjb25zdCBzdHJpbmcgJik7CnZvaWQgY3JjMzIoIGludCAqLCBjb25zdCBjaGFyICosIHVuc2lnbmVkIGludCk7CnZvaWQgZGVsZHVwKGNvbnN0IHN0cmluZyAmLCBib29sIG91dHB1dD10cnVlKTsKCgppbnQgbWFpbihpbnQgYXJnYywgY2hhciAqYXJndltdKSB7CmlmKGFyZ2M8MikgcmV0dXJuIDA7CnJlbW92ZSgiZHVwbGljYXRlLnR4dCIpOwpzdHJpbmcgcz1hcmd2WzFdOwppZiggcyE9Ii9kIiAmJiBzIT0iL0QiICkgewpmb3IoaW50IG49MTsgbjxhcmdjOyBuKyspIGRlbGR1cChhcmd2W25dKTsKcmV0dXJuIDA7IH0KLy8gYXJndlsyXeOBi+OCieOBneOCjOS7pemZjeOCkuWPluOCiumZpOOBjwpmb3IoaW50IG49MzsgbjxhcmdjOyBuKyspIGRlbGR1cChhcmd2W25dLCBmYWxzZSk7CmRlbGR1cChhcmd2WzJdKTsKcmV0dXJuIDA7IH0KCgp2b2lkIGRlbGR1cChjb25zdCBzdHJpbmcgJiBwYXRoLCBib29sIG91dHB1dCkgewpzdGF0aWMgdmVjdG9yPCBzZXQ8IGludD4gPiAgTSgyNTYpOwpzdGF0aWMgb2ZzdHJlYW0gZm87CnN0cmluZyBidWYsIHN0cjsKY2hhciBjWzVdOyBpbnQgbiwgeDsgdW5zaWduZWQgY2hhciBsOwppZnN0cmVhbSBpZnMocGF0aCk7CndoaWxlIChnZXRsaW5lKGlmcywgc3RyKSkgewppZihzdHIuZW1wdHkoKSkgY29udGludWU7Cm4gPSBzdHIubGVuZ3RoKCktMTsKaWYoc3RyW25dID09J1xyJyB8fCBzdHJbbl0gPT0nXG4nKSB7CnN0ci5yZXNpemUobik7CmlmKHN0ci5lbXB0eSgpKSBjb250aW51ZTsgfQpjcmMzMiggKGludCopYywgc3RyKTsKY1s0XSA9IChjaGFyKShzdHIubGVuZ3RoKCkgJiAweEZGKTsKbCA9ICoodW5zaWduZWQgY2hhciopYzsKeCA9ICooaW50KikmY1sxXTsKaWYoTVtsXS5maW5kKHgpICE9IE1bbF0uZW5kKCkpIHsKaWYoIW91dHB1dCkgY29udGludWU7IAppZighZm8uaXNfb3BlbigpKSBmby5vcGVuKCJkdXBsaWNhdGUudHh0Iik7CmZvPDxzdHIrIlxuIjsgCmNvbnRpbnVlOyB9Ck1bbF0uaW5zZXJ0KHgpOwppZighb3V0cHV0KSBjb250aW51ZTsKYnVmICs9IHN0ciArICJcbiI7CmlmKGJ1Zi5sZW5ndGgoKTwxMDAqMTAyNCkgY29udGludWU7CmNvdXQ8PGJ1ZjsKYnVmPSIiOyB9CmlmKG91dHB1dCkgY291dDw8YnVmOyB9CgoKCnZvaWQgY3JjMzIoaW50ICp4LCBjb25zdCBzdGQ6OnN0cmluZyAmcCkgeyBjcmMzMiggeCwgJnBbMF0sIHAuc2l6ZSgpICk7IH0Kdm9pZCBjcmMzMiggaW50ICp4LCBjb25zdCBjaGFyICpwICwgdW5zaWduZWQgaW50IGxlbmd0aCl7CnN0YXRpYyBpbnQgaW5pdCA9IDA7CnN0YXRpYyBpbnQgY3JjVFsyNTZdOwppZighaW5pdCkgeyAKaW5pdD0xOyAKZm9yIChpbnQgaT0wOyBpPDI1NjsgaSsrKSB7CmludCB6ID0gaTsKZm9yIChpbnQgaj04OyBqPjA7IGotLSkKaWYoeiYxKSB6PSh6Pj4xKV5DUkMzMl9QT0xZOyBlbHNlIHo+Pj0xOwpjcmNUW2ldPXo7IH19Cip4ID0gMHhGRkZGRkZGRjsKZm9yICh1bnNpZ25lZCBpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgCip4ID0gKCgqeCA+PiA4KSAmIDB4MDBGRkZGRkYpIF4gY3JjVFsoKnggXiBwW2ldKSAmIDB4RkYgXTsKKnggXj0gMHhGRkZGRkZGRjsgfQ==