这段c#代码有什么问题?
本文关键字:问题 什么 代码 这段 | 更新日期: 2023-09-27 18:12:31
我尝试创建一个倒排索引,但它不起作用。我的代码没有错误,但不能工作。有什么问题吗?
我每次都得到这个异常:KeyNotFoundException was unhandled : the given Key was not present in the dictionary
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static Dictionary<TItem, IEnumerable<TKey>> Invert<TKey, TItem>(Dictionary<TKey, IEnumerable<TItem>> dictionary)
{
return dictionary
.SelectMany(keyValuePair => keyValuePair.Value.Select(item => new KeyValuePair<TItem, TKey>(item, keyValuePair.Key)))
.GroupBy(keyValuePair => keyValuePair.Key)
.ToDictionary(group => group.Key, group => group.Select(keyValuePair => keyValuePair.Value));
}
static void Main(string[] args)
{
Console.WriteLine("files: ");
//read all the text document on the specified directory; change this directory based on your machine
foreach (string file in Directory.EnumerateFiles("D:''IR''", "*.txt"))
{
string contents = File.ReadAllText(file);
Console.WriteLine(contents);
Console.Write("find: ");
var find = Console.ReadLine();
var dictionary = file.Split().ToDictionary(files => files, files => File.ReadAllText(file).Split().AsEnumerable());
Console.WriteLine("{0} found in: {1}", find, string.Join(" ", Invert(dictionary)[find]));
}
}
}
}
我编辑了代码,现在它工作没有错误和异常。现在有另一个问题,它必须能够读取所有的文件只有一次,但它不能,我的意思是它每次读取其中一个,然后做查找过程,这不是我的观点,我需要一个输出,就像我写的下面。看来我应该把foreach(string file in Dictionary.EnumerateFiles("D:''IR''","*.txt"))
换成别的东西。但我不知道它是什么。
输出应该像这样:
files: file1 file2 file3
找到:
Edit:我测试了你的Invert
版本,这似乎工作得很好。您是否对默认的ToString()
输出感到困惑?如果您直接尝试打印Program.Invert(dictionary)[find]
,您将无法获得预期的输出,因为默认的ToString()
不是很有用(由于您尝试打印的对象没有覆盖object.ToString()
)。您必须遍历值列表并单独打印每个值。假设TKey
覆盖ToString()
,您将得到您想要的输出。例如
Console.WriteLine("{0} found in: ", find);
foreach (var val in Program.Invert(dictionary)[find])
{
Console.WriteLine(val);
}
上一个答案(为子孙后代保存):好吧,你提到你的Invert
方法有问题。我试着写一个我自己的Invert
方法,这是我想到的。我已经将方法调用分解为不同的部分,这样就可以清楚地看到我在做什么。
static Dictionary<TItem, IEnumerable<TKey>> Invert<TKey, TItem>(Dictionary<TKey, IEnumerable<TItem>> dictionary)
{
// Get collection of all the values which will be keys in the new inverted dictionary
var invertedDictKeys = dictionary.SelectMany(keyValPair => keyValPair.Value).Distinct();
// Perform the invert
var invertedDict =
invertedDictKeys.Select(
invertedKey =>
new KeyValuePair<TItem, IEnumerable<TKey>>(invertedKey, dictionary.Keys.Where(key => dict[key].Contains(invertedKey))));
// Convert to dictionary and return
return invertedDict.ToDictionary(keyValPair => keyValPair.Key, keyValPair => keyValPair.Value);
}