標籤:

用c語言怎麼實現把一個文件中所有的字元串進行篩選,重複的字元串只留下一個?

c語言,編程


這道題用C語言解決的話,有兩個難點:

1. C語言的標準庫中沒有接受一個字元串的方法。(fgets等都只能接受指定最大長度的字元串)

2. C語言的標準庫中沒有一個「去重」的方法。(無論是紅黑樹的set,還是hash的unordered_set)

所以,C語言的語法雖好,但苦於常用的庫缺失太多。對於實際應用,這不是一個缺點,因為每個公司都會開發自己需要的基本庫;但對於Show代碼,這就是淚點了。

說了好多廢話,還是用C++寫一個吧 ^_^

#include &
#include &
#include &
#include &
#include &
using namespace std;

int main( void )
{
ifstream src("c:/a.txt");
ofstream dst("c:/b.txt");

std::set& buf;
std::copy( std::istream_iterator&(src), std::istream_iterator&(), std::inserter(buf,buf.begin()) );
std::copy( buf.begin(), buf.end(), std::ostream_iterator&(dst,"
") );
}


純粹的C語言太久沒用我都忘記了,我也沒接觸過Haskell. 用一個半小時學了一下Haskell的基本語法, 我來提供一個Haskell的版本,大家有空再翻譯成C語言好了:)

module Main
where

import System.IO
import Control.Monad
import Data.List

main = do

let list = []
handle &<- openFile "test.txt" ReadMode contents &<- hGetContents handle let singlewords = words contents let list = nub singlewords print list hClose handle


純粹的C語言太久沒用我都忘記了,我來提供一個C#的版本,大家有空再翻譯成C語言好了:

File.WriteAllLines(@"C:a.txt", File.ReadAllLines(@"C:a.txt").Distinct());


題主要的C版本

#include &
#include &

int main() {
GError *err = NULL;

GIOChannel *chan = g_io_channel_new_file("input", "r", err);
if (err != NULL) {
fprintf(stderr, "open file: %s
", err-&>message);
return -1;
}

gchar *line;
gsize len, term_pos;
GHashTable *set = g_hash_table_new(g_str_hash, g_str_equal);
while (g_io_channel_read_line(chan, line, len, term_pos, err) == G_IO_STATUS_NORMAL) {
if (g_hash_table_contains(set, line)) {
g_free(line);
continue;
}
g_hash_table_add(set, line);
printf("%s", line);
}
}


純粹的C語言太久沒用,我其實還記得。

先用C語言實現一個SHELL,要符合POSIX的那種

然後

cat file.txt | sort | uniq

即可。


純粹的C語言太久沒用我都忘記了,我來提供一個二進位的版本,大家有空再翻譯成C語言好了:

10011100110101001000111100111000111......


擼個字典(Trie)樹咯。


純粹的C語言太久沒用我都忘記了,我來提供一個python的版本,大家有空再翻譯成C語言好了:

file = open("test")
ans=list(set(re.split(r"[^w]+",file.read())))

(逃


hash表,讀到新的hash值存新的字元串,對應hash值就置1,文件太大想辦法拆一下即可。

但是這樣字串的hash值可能會重複,這個時候可以給收集到的字元串做個trie樹,重複字串通過trie樹驗證一下。


純粹的C語言太久沒用我都忘記了,我來提供一個半人工的版本,大家有空再翻譯成C語言好了:

1.用文本編輯器打開該文檔。
2.令i=1,j=0。
3.若第i個字元串存在,進入下面的循環。
4.搜索文檔中第i個字元串,令搜索結果數為j。
5.如果j&>1,則刪除除首次出現的字元串之外的其他相同的字元串。
6.i=i+1。(循環結束,返回第3步)
7.保存文件,退出文本編輯器。


純粹的C語言太久沒用我都忘記了,我來提供一個php的版本:

&


純粹的C語言太久沒用我都忘記了,搞個 C++ 的吧:

#include &
#include &
#include &
#include &

using namespace std;

int main()
{
unordered_set& container;
ifstream fin("test.txt");
string line;
while (getline(fin, line)) {
container.insert(line);
}

for (auto s: container) {
cout &<&< s &<&< endl; } return 0; }


純粹的C語言太久沒用我都忘記了,我來提供一個Java版本,大家有空再翻譯成C語言好了:

System.out.println(
Files.readAllLines(Paths.get("/Users/pluszhang/Desktop/text.txt"))
.stream()
.collect(Collectors.toSet())
);


我建議題主換個地方問。去Stack Overflow或者SegmentFault問編程的問題


說的好像c不能調介面一樣。

Set* set = newSet();

while (fgets(buffer, sizeof(buffer), file_in) != NULL) {

if (setInsert(set, buffer)) {

fwrite(buffer, 1, strlen(buffer), file_out);

}

}

// TODO: set.c


python大法好 set


有三個思路:(先假設文件中字元串按行劃分)

  • 第一種,逐個讀取字元串並寫入新文件,寫入前與已寫入的作對比strcmp,若相同就不寫;
  • 第二種,將字元串化為Hash值,寫入前與已寫入的字元串的Hash值對比,若相同就不寫;
  • 第三種,逐個讀取字元串並將其轉化到同一棵節點為字元的樹上,最後遍歷樹得出所有串。


純粹的C語言太久沒用我都忘記了,我來提供一個lua的版本,大家有空再翻譯成C語言好了:

local file, err = io.open("in.txt")
if not err then
local outfile = io.open("out.txt", "w+")
local tAllNames = {}

for line in io.lines(sFileFullName) do
if not tAllNames[line] then
tAllNames[line] = true

outfile:write(line .. "
")
end
end
end

真實項目用過的,臨時改了下,不要在意報錯細節。。。

(逃


呃,字元串數量,長度多少?不同情況適用不同解決方案。另外為什麼限定c語言呢?學校作業么?


看了評論發現如今小白到大牛, 真的少人用純粹的C語言了. 時代變了


推薦閱讀:

C語言中的一個小問題?
C 指針傳遞變數為什麼無法修改變數值?
不學C語言,直接學C++會有問題嗎?
怎麼理解 C 語言是面向過程的語言,C++ 是面向對象的語言。?
gcc環境下不能使用gets怎麼辦?

TAG:C編程語言 |