我必须编写一个使用哈希表的程序,并且用户输入键/值。在程序中,我必须输出所有键,但是如果任何键以小'a'开头,我必须以大'A'开头。我在最后一步遇到了问题。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Hashtable hashtable = new Hashtable();
for (int i = 0; i < 10; i++)
{
Console.WriteLine("Vnesete kluc");
string kluc = Console.ReadLine();
Console.WriteLine("Vnesete podatok");
string podatok = Console.ReadLine();
hashtable.Add(kluc, podatok);
}
foreach (string klucevi in hashtable.Keys)
{
if (klucevi[0] == 'a')
{
klucevi[0] = 'A';
}
Console.WriteLine(klucevi);
}
}
}
}
我在转换字符串的第一个元素的行上出现错误,如果它是'a'到'A'。
答案 0 :(得分:3)
您无法动态更改密钥。最简单的方法是检查添加到集合中的之前的键:
for (int i = 0; i < 10; i++)
{
Console.WriteLine("Vnesete kluc");
string kluc = Console.ReadLine();
if (kluc.StartsWith("a"))
kluc = "A" + kluc.Substring(1);
Console.WriteLine("Vnesete podatok");
string podatok = Console.ReadLine();
hashtable.Add(kluc, podatok);
}
答案 1 :(得分:1)
您的问题与哈希表无关。您有编译错误,因为在.NET中字符串是不可变的。
其次,这是无关的,不能将foreach循环变量赋值给。
所以,而不是
foreach (string klucevi in *whatever*)
{
if (klucevi[0] == 'a')
{
klucevi[0] = 'A';
}
Console.WriteLine(klucevi);
}
使用
foreach (string klucevi in *whatever*)
{
var temp = klucevi;
if (temp[0] == 'a')
{
StringBuilder sb = new StringBuilder(temp);
sb[0] = 'A';
temp = sb.ToString();
}
Console.WriteLine(temp);
}
不要忘记添加using System.Text;
声明。
更新: 上面的aswer显示了一种在.NET中修改字符串的通用方法,而不仅仅是替换一个字符。
此外,有些人对这种方法的效率表示担忧。他们错了。有关Strings Undocumented的详尽文章中的更多信息。
更新2:
我喜欢受到挑战。虽然它与手头的问题完全无关,但与使用"A" + temp.Substring(1)
相比,讨论了使用StringBuilder的效率。因为我喜欢事实,并且我认为一些读者会同意,所以我运行了一些基准。
我使用.NET 4.5作为32位和64位进程在64位Windows 7机器上运行测试。事实证明,StringBuilder方法总是比替代方法快20%左右。内存使用率大致相同。 YMMV。
对于那些关心重复测试的人来说,这是源代码:
using System;
using System.Diagnostics;
using System.Text;
static class Program
{
static void Main(string[] args)
{
for (int length = 50; length <= 51200; length = length * 2)
{
string input = new string(' ', length);
// warm up
PerformTest(input, 1);
// actual test
PerformTest(input, 100000);
}
}
static void PerformTest(string input, int iterations)
{
GC.Collect();
GC.WaitForFullGCComplete();
int gcRuns = GC.CollectionCount(0);
Stopwatch sw = Stopwatch.StartNew();
for (int i = iterations; i > 0; i--)
{
StringBuilder sb = new StringBuilder(input);
sb[0] = 'A';
input = sb.ToString();
}
long ticksWithStringBuilder = sw.ElapsedTicks;
int gcRunsWithStringBuilder = GC.CollectionCount(0) - gcRuns;
GC.Collect();
GC.WaitForFullGCComplete();
gcRuns = GC.CollectionCount(0);
sw = Stopwatch.StartNew();
for (int i = iterations; i > 0; i--)
{
input = "A" + input.Substring(1);
}
long ticksWithConcatSubstring = sw.ElapsedTicks;
int gcRunsWithConcatSubstring = GC.CollectionCount(0) - gcRuns;
if (iterations > 1)
{
Console.WriteLine(
"String length: {0, 5} With StringBuilder {1, 9} ticks {2, 5} GC runs, alternative {3, 9} ticks {4, 5} GC Runs, speed ratio {5:0.00}",
input.Length,
ticksWithStringBuilder, gcRunsWithStringBuilder,
ticksWithConcatSubstring, gcRunsWithConcatSubstring,
((double)ticksWithStringBuilder) / ((double)ticksWithConcatSubstring));
}
}
}