查找文件中的唯一字符

问题描述 投票:16回答:21

我有一个包含450,000+条目行的文件。每个条目的长度约为7个字符。我想知道的是此文件的唯一字符。

例如,如果我的文件是以下文件;

Entry
-----
Yabba
Dabba
Doo

然后结果将是

[唯一字符:{abdoy}

注意,我不在乎大小写,也不需要订购结果。有些东西告诉我,这对于Linux人员来说很容易解决。

更新

我正在寻找一个非常快速的解决方案。我真的不想创建代码来遍历每个条目,遍历每个字符...等等。我正在寻找一个不错的脚本解决方案。

更新2

通过快速,我的意思是快速实施...不一定快速运行。

search parsing scripting
21个回答
4
投票
PowerShell示例:

gc file.txt | select -Skip 2 | % { $_.ToCharArray() } | sort -CaseSensitive -Unique 产生:

Dÿ一种bo

我喜欢它很容易阅读。

EDIT:这是一个更快的版本:

$letters = @{} ; gc file.txt | select -Skip 2 | % { $_.ToCharArray() } | % { $letters[$_] = $true } ; $letters.Keys


1
投票
使用bash的替代解决方案:

sed "s/./\l\0\n/g" inputfile | sort -u | grep -vc ^$

EDIT抱歉,我实际上误解了这个问题。上面的代码

counts个唯一字符。仅在最后省略c开关显然可以解决问题,但是,此解决方案对saua的解决方案没有真正的优势(特别是因为他现在使用相同的sed模式而不是显式捕获)。


1
投票
import java.util.*; import java.io.*; public class Unique { public static void main( String [] args ) throws IOException { int c = 0; Set s = new TreeSet(); while( ( c = System.in.read() ) > 0 ) { s.add( Character.toLowerCase((char)c)); } System.out.println( "Unique characters:" + s ); } }

您将这样调用它:

type yourFile | java Unique

cat yourFile | java Unique

例如,此问题的HTML中的唯一字符是:

Unique characters:[ , , ,  , !, ", #, $, %, &, ', (, ), +, ,, -, ., /, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, :, ;, <, =, >, ?, @, [, \, ], ^, _, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, {, |, }]

0
投票

0
投票
var seenAlreadyMap={}; var seenAlreadyArray=[]; while (!system.stdin.eof) { var L = system.stdin.readLine(); for (var i = L.length; i-- > 0; ) { var c = L[i].toLowerCase(); if (!(c in seenAlreadyMap)) { seenAlreadyMap[c] = true; seenAlreadyArray.push(c); } } } system.stdout.writeln(seenAlreadyArray.sort().join(''));

0
投票
file = open('location.txt', 'r') letters = {} for line in file: if line == "": break for character in line.strip(): if character not in letters: letters[character] = True file.close() print "Unique Characters: {" + "".join(letters.keys()) + "}"

0
投票
#include<stdio.h> #define CHARSINSET 256 #define FILENAME "location.txt" char buf[CHARSINSET + 1]; char *getUniqueCharacters(int *charactersInFile) { int x; char *bufptr = buf; for (x = 0; x< CHARSINSET;x++) { if (charactersInFile[x] > 0) *bufptr++ = (char)x; } bufptr = '\0'; return buf; } int main() { FILE *fp; char c; int *charactersInFile = calloc(sizeof(int), CHARSINSET); if (NULL == (fp = fopen(FILENAME, "rt"))) { printf ("File not found.\n"); return 1; } while(1) { c = getc(fp); if (c == EOF) { break; } if (c != '\n' && c != '\r') charactersInFile[c]++; } fclose(fp); printf("Unique characters: {%s}\n", getUniqueCharacters(charactersInFile)); return 0; }

0
投票
for char in a b c d e f g h i j k l m n o p q r s t u v w x y z; do if [ ! -z "`grep -li $char file`" ]; then echo -n $char; fi; done; echo

我本来可以把它做成单线的,但只想使其易于阅读。

((编辑:忘记了-i切换到grep)

0
投票
f = open("location.txt", "r") # open file ll = sorted(list(f.read().lower())) #Read file into memory, split into individual characters, sort list ll = [val for idx, val in enumerate(ll) if (idx == 0 or val != ll[idx-1])] # eliminate duplicates f.close() print "Unique Characters: {%s}" % "".join(ll) #print list of characters, carriage return will throw in a return

它不会遍历每个字符,它也相对较短。您不希望用它打开500 MB的文件(取决于您的RAM),但是对于较短的文件,这很有趣:)

我还必须添加我的最终攻击!!!!诚然,我通过使用标准输入而不是文件消除了两行,我还将活动代码从3行减少到2行。基本上,如果我用上面一行的表达式替换了打印行中的ll,那么我本来可以有1行的活动代码和一行导入代码...无论如何,我们现在很开心:)

import itertools, sys # read standard input into memory, split into characters, eliminate duplicates ll = map(lambda x:x[0], itertools.groupby(sorted(list(sys.stdin.read().lower())))) print "Unique Characters: {%s}" % "".join(ll) #print list of characters, carriage return will throw in a return


0
投票
如果是这样,由于Python documentation声明,此处显示的代码可以进行简化:

最好将字典视为无序键集:值对,要求钥匙是唯一的(在一本字典内)...您使用已经存在的密钥进行存储在使用中,与那个钥匙被忘记了。

因此,可以删除此行代码,因为字典键始终始终是唯一的:

if character not in letters:

这应该使它更快一些。


0
投票
using System; using System.IO; using System.Collections; using System.Diagnostics; namespace ConsoleApplication { class Program { static void Main(string[] args) { FileInfo fileInfo = new FileInfo(@"C:/data.txt"); Console.WriteLine(fileInfo.Length); Stopwatch sw = new Stopwatch(); sw.Start(); Hashtable table = new Hashtable(); StreamReader sr = new StreamReader(@"C:/data.txt"); while (!sr.EndOfStream) { char c = Char.ToLower((char)sr.Read()); if (!table.Contains(c)) { table.Add(c, null); } } sr.Close(); foreach (char c in table.Keys) { Console.Write(c); } Console.WriteLine(); sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); } } }

产生输出

4093767 
mytojevqlgbxsnidhzupkfawr 
c 
889 
Press any key to continue . . .

输出的第一行告诉您C:/data.txt中的字节数(454,863 *(7 + 2)= 4,093,767字节)。输出的后两行是C:/data.txt中的唯一字符(包括换行符)。输出的最后一行告诉您代码在2.80 GHz Pentium 4上执行所需的毫秒数。


17
投票
while read -n 1 char; do echo "$char"; done < entry.txt | tr [A-Z] [a-z] | sort -u

UPDATE:仅此而已,因为我很无聊并且仍然在考虑这个问题,所以这里是一个使用set的C ++版本。如果运行时间很重要,那么这将是我推荐的选项,因为C ++版本需要花费超过半秒的时间来处理具有450,000+条目的文件。 

#include <iostream> #include <set> int main() { std::set<char> seen_chars; std::set<char>::const_iterator iter; char ch; /* ignore whitespace and case */ while ( std::cin.get(ch) ) { if (! isspace(ch) ) { seen_chars.insert(tolower(ch)); } } for( iter = seen_chars.begin(); iter != seen_chars.end(); ++iter ) { std::cout << *iter << std::endl; } return 0; }

请注意,我忽略空格,并且根据要求不区分大小写。
对于450,000+的入口文件(chars.txt),这是示例运行时间:

[user@host]$ g++ -o unique_chars unique_chars.cpp [user@host]$ time ./unique_chars < chars.txt a b d o y real 0m0.638s user 0m0.612s sys 0m0.017s


0
投票

0
投票
file = open('location', 'r') letters = [] for line in file: for character in line: if character not in letters: letters.append(character) print(letters)

10
投票
sed -e "s/./\0\n/g" inputfile | sort -u

这不是很好,它不是很快,并且输出也不完全是指定的,但是应该可以正常工作...

为了更加荒谬,我介绍了将输出转储到一行的版本:

sed -e "s/./\0\n/g" inputfile | sort -u | while read c; do echo -n "$c" ; done


6
投票

5
投票
#include <stdio.h> int main(void) { int chars[256] = {0}, c; while((c = getchar()) != EOF) chars[c] = 1; for(c = 32; c < 127; c++) // printable chars only { if(chars[c]) putchar(c); } putchar('\n'); return 0; }

编译,然后执行

cat file | ./a.out

要获得file中唯一可打印字符的列表。


3
投票
s = open("data.txt", "r").read() print "Unique Characters: {%s}" % ''.join(set(s))

带有设置的Python(具有更好的输出)

import re

text = open("data.txt", "r").read().lower()
unique = re.sub('\W, '', ''.join(set(text))) # Ignore non-alphanumeric

print "Unique Characters: {%s}" % unique

2
投票
为什么需要一个限制来执行它的“脚本”?

脚本到底是什么?

Python会做吗?

如果是,那么这是一种解决方案:

import sys; s = set([]); while True: line = sys.stdin.readline(); if not line: break; line = line.rstrip(); for c in line.lower(): s.add(c); print("".join(sorted(s)));


2
投票
Create an array of unsigned ints, initialized to zero. Iterate though the in memory file, using each byte as a subscript into the array. increment that array element. Discard the in memory file Iterate the array of unsigned int if the count is not zero, display the character, and its corresponding count.

1
投票
© www.soinside.com 2019 - 2024. All rights reserved.