Skip to content

Instantly share code, notes, and snippets.

@pkuderov
Last active April 19, 2017 08:59
Show Gist options
  • Save pkuderov/788c90a79c49d643336ba41f58dc9aee to your computer and use it in GitHub Desktop.
Save pkuderov/788c90a79c49d643336ba41f58dc9aee to your computer and use it in GitHub Desktop.
SO: How to replace chars inorder
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace CharReplacement
{
internal class Program
{
private static void Main()
{
var replacementRule = Enumerable
.Range(0, 28)
.Select(x => (char) ('a' + x))
.Select(c => new CharItem {Value = c, Value2 = char.ToUpper(c)})
.ToList()
.ToDictionary(item => item.Value, item => item.Value2);
const string input = "I've got this foreach loop that replaces a char in a string in the correct order, but it's to slow..The input string can have different lengths.. string lengths range 1000 - 1000000 Each char look up only takes, 1.2 milliseconds..But it's the input string that slows it down, anyway to replace chars faster..";
//var result = ReplaceWithTpl(input, replacementRule);
var result = ReplaceInBatch(replacementRule, input);
Console.WriteLine(result);
}
private static void TestWithFile(IReadOnlyDictionary<char, char> replacementRule)
{
foreach (var line in File.ReadLines(@"InputFiles\1.txt"))
{
var lineResult = ReplaceInBatch(replacementRule, line);
//... apply encryption to the lineResult
}
}
private static string ReplaceWithTpl(IReadOnlyDictionary<char, char> replacementRule, string input)
{
const int batchCount = 8; // ~ logical processor count
var batchSize = (input.Length - 1) / batchCount + 1;
var result = Enumerable
.Range(0, batchCount)
.Select(
ind => new
{
Index = ind,
StringPart = input.Substring(
Math.Min(input.Length, batchSize * ind),
Math.Min(batchSize, input.Length - Math.Min(input.Length, batchSize * ind))
)
})
.AsParallel()
.Select(
batch => new
{
batch.Index,
Result = ReplaceInBatch(replacementRule, batch.StringPart)
})
.OrderBy(batch => batch.Index)
.Aggregate(new StringBuilder(input.Length), (sb, batch) => sb.Append(batch.Result))
.ToString();
return result;
}
private static StringBuilder ReplaceInBatch(IReadOnlyDictionary<char, char> replacementRule, string batch)
{
var sb = new StringBuilder();
foreach (var c in batch)
{
char tempC;
if (replacementRule.TryGetValue(c, out tempC))
{
sb.Append(tempC);
}
}
return sb;
}
}
public class CharItem
{
public char Value { get; set; }
public char Value2 { get; set; }
public override string ToString()
{
return "1." + Value + "| 2." + Value2;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment