在 C# 中更改哈希表中字符串的一个元素
本文关键字:一个 元素 字符串 哈希表 | 更新日期: 2023-09-27 18:37:14
我必须编写一个使用哈希表的程序,键/值由用户输入。在程序中,我必须输出所有键,但是如果任何键以小"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"的行上收到错误。
您无法动态更改密钥。最简单的方法是在添加到集合之前检查密钥:
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);
}
您的问题与哈希表无关。您有一个编译错误,因为在 .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 中修改字符串的通用方法,而不仅仅是替换一个字符。
此外,有些人对这种方法的效率表示担忧。他们错了。在这篇关于未记录的字符串的练习文章中提供了更多信息。
更新 2:我喜欢接受挑战。虽然它与手头的问题完全无关,但与使用"A" + temp.Substring(1)
相比,关于使用 StringBuilder 的有效性的讨论已经合并。因为我喜欢事实,我想有些读者会同意,所以我运行了一个小基准。
我在 64 位 Windows 7 机器上运行了测试,其中 .NET 4.5 作为 32 位和 64 位进程。事实证明,StringBuilder方法总是比替代方案快20%左右。内存使用量大致相同。扬子晚报.
对于那些愿意重复测试的人,以下是源代码:
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));
}
}
}