我有一个面试问题,问:
文本文件包含以下行>
1: A C D 4: A B 5: D F 7: A E 9: B C
*每一行都有一个唯一的整数后跟冒号和一个或 更多信件。这些信是 分隔空格(一个或多个)>
您选择的#2 Write a short program in the language
输出已排序的 列表如
A: 1 4 7 B: 4 9 C: 1 9 D: 1 5 E: 7 F: 5
我不是在找人来解决它,但我总是对这样的问题感到困惑。我想在C#中这样做,并且想知道我应该将每一行存储在一个二维数组中吗?处理这个问题的最佳方法是什么。存储后,我如何用字母而不是数字重新连接每一行?
只是在这里寻找指示。
答案 0 :(得分:2)
您可以通过为一组数字创建Lookup
映射字母来解决问题。您可以使用扩展方法ToLookup
创建Lookup
。
警告:前方的剧透
使用LINQ你可以这样做(打破无效输入):
var text = @"1: A C D
4: A B
5: D F
7: A E
9: B C";
var lookup = text
.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
.Select(
line => new {
Number = Int32.Parse(line.Split(':').First()),
Letters = line.Split(':').Skip(1).First().Split(
new[] {' '}, StringSplitOptions.RemoveEmptyEntries
)
}
)
.SelectMany(x => x.Letters, (x, letter) => new { x.Number, Letter = letter })
.OrderBy(x => x.Letter)
.ToLookup(x => x.Letter, x => x.Number);
foreach (var item in lookup)
Console.WriteLine(item.Key + ": " + String.Join(" ", item.ToArray()));
答案 1 :(得分:1)
有助于你解决这个问题的事情
IDictionary<char, IList<int> >
另一个Linq Masturbatory实施(“看马!没有循环!”)
using System;
using System.IO;
using System.Linq;
public static class Program
{
public static void Main(string[] args)
{
File.ReadAllLines("input.txt")
.Select(line =>
{
var split = line.Split(":".ToCharArray(), 2);
return new { digit = split[0].Trim().Substring(0,1),
chars = split[1]
.Split(" \t".ToCharArray())
.Select(s=>s.Trim())
.Where(s => !String.IsNullOrEmpty(s))
.Select(s => s[0])
};
})
.SelectMany(p => p.chars.Select(ch => new { p.digit, ch }))
.GroupBy(p => p.ch, p => p.digit)
.ToList()
.ForEach(g => Console.WriteLine("{0}: {1}", g.Key, string.Join(" ", g)));
}
}
当然,您可以将GroupBy
替换为ToLookup
答案 2 :(得分:1)
如果您熟悉LINQ,以下代码可以为您提供所需内容:
var result = File.ReadAllLines("inFile").SelectMany(line =>
{
var ar = line.Split(" ".ToCharArray());
var num = int.Parse(ar[0].Split(":".ToCharArray())[0]);
return ar.Skip(1).Select(s => new Tuple<string, int>(s, num));
}).GroupBy(t => t.Item1).OrderByDescending(g => g.Count())
.Select(g => g.Key + ": " + g.Select(t => t.Item2.ToString()).Aggregate( (a,b) => a + " " + b));
File.WriteAllLines("outFile", result);
答案 3 :(得分:1)
我知道你说你不想要完整答案,但这种事情很有趣。看起来其他人已经提出了类似的解决方案,但这是代表它的另一种方式 - 代码的“一行”(但很多括号!):)
var data = @"1: A C D
4: A B
5: D F
7: A E
9: B C";
Console.WriteLine(
String.Join(
Environment.NewLine,
(from line in data.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
let lineParts = line.Split(new[] { ':', ' ' }, StringSplitOptions.RemoveEmptyEntries)
from letter in lineParts.Skip(1)
select new { Number = lineParts[0], Letter = letter })
.ToLookup(l => l.Letter, l => l.Number)
.OrderBy(l => l.Key)
.Select(l => String.Format("{0}: {1}", l.Key, String.Join(" ", l)))));
哦,我会在制作中编写类似的代码吗?可能不是,但这样的练习很有趣!
答案 4 :(得分:0)
我将使用Dictionary<string,List<int>>
我将读取输入,并在键A,C,D,A键A,B等的列表中添加1,因此结果只是一个字母查找。
所以这样,以一种非深奥的方式:
string inp = @"1: A C D
4: A B
5: D F
7: A E
9: B C";
Dictionary<string, List<int>> res = new Dictionary<string, List<int>>();
StringReader sr = new StringReader(inp);
string line;
while (null != (line = sr.ReadLine()))
{
if (!string.IsNullOrEmpty(line))
{
string[] tokens = line.Split(": ".ToArray(),StringSplitOptions.RemoveEmptyEntries);
int idx = int.Parse(tokens[0]);
for (int i = 1; i < tokens.Length; ++i)
{
if (!res.ContainsKey(tokens[i]))
res[tokens[i]] = new List<int>();
res[tokens[i]].Add(int.Parse(tokens[0]));
}
}
}
res将包含letter-&gt;数字列表的结果。
答案 5 :(得分:0)
使用Split(“:”)和Split(“”)进行字符串解析。 然后填写
Dictionary<int, List<string>>
并将其翻译为
Dictionary<string, List<int>>
答案 6 :(得分:0)
您可以将输入存储在IDictionary中,然后将其反转以生成输出。
答案 7 :(得分:0)
我看到已经发布了多个相似(循环)和不那么相似(linq)的解决方案但是因为我写了这个,我以为我会把它扔进混合中。
static void Main(string[] args)
{
var result = new SortedDictionary<char, List<int>>();
var lines = System.IO.File.ReadAllLines(@"input.txt");
foreach (var line in lines)
{
var split = line.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
var lineNumber = Int32.Parse(split[0].Substring(0,1));
foreach (var letter in split.Skip(1))
{
var key = letter[0];
if (!result.ContainsKey(key))
{
result.Add(key, new List<int> { lineNumber });
}
else
{
result[key].Add(lineNumber);
}
}
}
foreach (var item in result)
{
Console.WriteLine(String.Format("{0}: {1}", item.Key, String.Join(" ", item.Value)));
}
Console.ReadKey();
}
答案 8 :(得分:0)
面试过程的一个重要部分是询问和验证假设。虽然您的描述声明文件的结构为整数后跟字母,但您给出的示例按递增顺序显示整数。如果是这种情况,您可以避免所有LINQ疯狂并实施更有效的解决方案:
var results = new Dictionary<char, List<int>>();
foreach (var line in File.ReadAllLines(@"input.txt"))
{
var split = line.Split(new []{' '}, StringSplitOptions.RemoveEmptyEntries);
var num = int.Parse(split[0].TrimEnd(':'));
for (int i = 1; i < split.Length; i++)
{
char letter = split[i][0];
if (!results.ContainsKey(letter))
results[letter] = new List<int>();
results[letter].Add(num);
}
}