String substitution (C#) - c#

Programming in c#.
I'm trying to substitute every char in a string with another char (Encryption), but I need some help. I was going to do this using two arrays, one with the alphabet in it, then the other with the substitute values, but I realized I'd have to do a else-if the size of the whole alphabet, which I don't really have time for. I'd like to know if there is an easier, faster way. This is what I have so far
private string EncryptFn(string Sinput)
{
string STencryptedResult = "Null for now";
char[] CAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
char[] Encrypt = "QWERTYUIOPASDFGHJKLZXCVBNM".ToCharArray();
return STencryptedResult;
}
Thanks

You could use a Dictionary:
var map = new Dictionary<char,char> {
{ 'A', 'Q' },
{ 'B', 'W' },
// etc
};
Then it becomes pretty easy to map each char with something like this:
var result = new StringBuilder();
foreach( var fromChar in inputString ) {
char toChar;
if( ! map.TryGetValue(fromChar, out toChar) ) {
// Do something with missing char
}
result.Append(toChar);
}

It isn't a very strong encryption, but you the following version would be extremely efficient and requires very little data to define the encryption:
private string EncryptFn(string Sinput)
{
string coding = "QWERTYUIOPASDFGHJKLZXCVBNM";
StringBuilder result = new StringBuilder();
foreach (char c in Sinput)
{
int index = (Char.ToUpper(c) - 'A');
if (index >= 0 && index < coding.Length)
result.Append(coding[index]);
else
result.Append(c);
}
return result.ToString();
}

You might consider BitWise operations, they work great for encrypting and decrypting data. See the following.
Byte array cryptography

Related

How to reverse string in C# [duplicate]

I didn't get the problem - I was trying to do a simple action:
for(i = x.Length-1, j = 0 ; i >= 0 ; i--, j++)
{
backx[j] = x[i];
}
Both are declared:
String x;
String backx;
What is the problem ? It says the error in the title...
If there is a problem - is there another way to do that?
The result (As the name 'backx' hints) is that backx will contain the string X backwards.
P.S. x is not empty - it contains a substring from another string.
Strings are immutable: you can retrieve the character at a certain position, but you cannot change the character to a new one directly.
Instead you'll have to build a new string with the change. There are several ways to do this, but StringBuilder does the job in a similar fashion to what you already have:
StringBuilder sb = new StringBuilder(backx);
sb[j] = x[i];
backx = sb.ToString();
EDIT: If you take a look at the string public facing API, you'll see this indexer:
public char this[int index] { get; }
This shows that you can "get" a value, but because no "set" is available, you cannot assign values to that indexer.
EDITx2: If you're looking for a way to reverse a string, there are a few different ways, but here's one example with an explanation as to how it works: http://www.dotnetperls.com/reverse-string
String is immutable in .NET - this is why you get the error.
You can get a reverse string with LINQ:
string x = "abcd";
string backx = new string(x.Reverse().ToArray());
Console.WriteLine(backx); // output: "dcba"
String are immuatable. You have convert to Char Array and then you would be able to modify.
Or you can use StringBuilder.
for example
char[] wordArray = word.ToCharArray();
In C# strings are immutable. You cannot "set" Xth character to whatever you want. If yo uwant to construct a new string, or be able to "edit" a string, use i.e. StringBuilder class.
Strings are immutable in C#. You can read more about it here: http://msdn.microsoft.com/en-us/library/362314fe.aspx
Both the variables you have are string while you are treating them as if they were arrays (well, they are). Of course it is a valid statement to access characters from a string through this mechanism, you cannot really assign it that way.
Since you are trying to reverse a string, do take a look at this post. It has lot of information.
public static string ReverseName( string theName)
{
string revName = string.Empty;
foreach (char a in theName)
{
revName = a + revName;
}
return revName;
}
This is simple and does not involve arrays directly.
The code below simply swaps the index of each char in the string which enables you to only have to iterate half way through the original string which is pretty efficient if you're dealing with a lot of characters. The result is the original string reversed. I tested this with a string consisting of 100 characters and it executed in 0.0000021 seconds.
private string ReverseString(string testString)
{
int j = testString.Length - 1;
char[] charArray = new char[testString.Length];
for (int i = 0; i <= j; i++)
{
if (i != j)
{
charArray[i] = testString[j];
charArray[j] = testString[i];
}
j--;
}
return new string(charArray);
}
In case you need to replace e.g. index 2 in string use this (it is ugly, but working and is easily maintainbable)
V1 - you know what you want to put their. Here you saying in pseudocode string[2] = 'R';
row3String.Replace(row3String[2], 'R');
V2 - you need to put their char R or char Y. Here string[2] = 'R' if was 'Y' or if was not stay 'Y' (this one line if needs some form of else)
row3String.Replace(row3String[2], row3String[2].Equals('Y') ? 'R' : 'Y');

Cannot implicitly convert type 'char*' to 'bool'

The program below is from the book "Cracking the coding interview", by Gayle Laakmann McDowell.
The original code is written in C.
Here is the original code:
void reverse(char *str) {
char * end = str;
char tmp;
if (str) {
while (*end) {
++end;
}
--end;
while (str < end) {
tmp = *str;
*str++ = *end;
*end-- = tmp;
}
}
}
I am trying to convert it in C#. After researching via Google and playing with the code, below is what I have. I am a beginner and really stuck. I am not getting the value I am expecting. Can someone tell me what I am doing wrong?
class Program
{
unsafe void reverse(char *str)
{
char* end = str;
char tmp;
if (str) // Cannot implicitly convert type 'char*' to 'bool'
{
while(*end) // Cannot implicitly convert type 'char*' to 'bool'
{
++end;
}
--end;
while(str < end)
{
tmp = *str;
*str += *end;
*end -= tmp;
}
}
}
public static void Main(string[] args)
{
}
}
I can't really remember if this ever worked in C#, but I am quite certain it should not work now.
To start off by answering your question. There is no automatic cast between pointers and bool. You need to write
if(str != null)
Secondly, you can't convert char to bool. Moreover, there is no terminating character for C# strings, so you can't even implement this. Normally, you would write:
while(*end != '\0') // not correct, for illustration only
But there is no '\0' char, or any other magic-termination-char. So you will need to take an int param for length.
Going back to the big picture, this sort of code seems like a terribly inappropriate place to start learning C#. It's way too low level, few C# programmers deal with pointers, chars and unsafe contexts on a daily basis.
... and if you must know how to fix your current code, here's a working program:
unsafe public static void Main(string[] args)
{
var str = "Hello, World";
fixed(char* chr = str){
reverse(chr, str.Length);
}
}
unsafe void reverse(char *str, int length)
{
char* end = str;
char tmp;
if (str != null) //Cannot implicitly convert type 'char*' to 'bool'
{
for(int i = 0; i < length; ++i) //Cannot implicitly convert type 'char*' to 'bool'
{
++end;
}
--end;
while(str<end)
{
tmp = *str;
*str = *end;
*end = tmp;
--end;
++str;
}
}
}
Edit: removed a couple of .Dump() calls, as I was trying it out in LINQPad :)
C# is not like C in that you cannot use an integer value as an implicit bool. You need to manually convert it. One example:
if (str != 0)
while (*end != 0)
A word of warning: If you are migrating from C, there are a few things that can trip you up in a program like this. The main one is that char is 2 bytes. strings and chars are UTF-16 encoded. The C# equivalent of char is byte. Of course, you should use string rather than C-strings.
Another thing: If you got your char* by converting a normal string to a char*, forget your entire code. This is not C. Strings are not null-terminated.
Unless this is homework, you would much rather be doing something like this:
string foo = "Hello, World!";
string bar = foo.Reverse(); // bar now holds "!dlroW ,olleH";
As you discovered, you can use pointers in C#, if you use the unsafe keyword. But you should do that only when really necessary and when you really know what you're doing. You certainly shouldn't use pointers if you're just beginning with the language.
Now, to your actual question: you are given a string of characters and you want to reverse it. Strings in C# are represented as the string class. And string is immutable, so you can't modify it. But you can convert between a string and an array of characters (char[]) and you can modify that. And you can reverse an array by using the static method Array.Reverse(). So, one way to write your method would be:
string Reverse(string str)
{
if (str == null)
return null;
char[] array = str.ToCharArray(); // convert the string to array
Array.Reverse(array); // reverse the array
string result = new string(array); // create a new string out of the array
return result; // and return it
}
If you wanted to write the code that actually does the reversing, you can do that too (as an exercise, I wouldn't do it in production code):
string Reverse(string str)
{
if (str == null)
return null;
char[] array = str.ToCharArray();
// use indexes instead of pointers
int start = 0;
int end = array.Length - 1;
while (start < end)
{
char tmp = array[start];
array[start] = array[end];
array[end] = tmp;
start++;
end--;
}
return new string(array);
}
Try making it more explicit what you are checking in the conditions:
if(str != null)
while(*end != '\0')
You might also want to watch out for that character swapping code: it looks like you've got a +/- in there. If that's supposed to update your pointer positions, I'd suggest making those separate operations.

How to check if a string has at least 1 alphabetic character? [duplicate]

This question already has answers here:
How can I generate random alphanumeric strings?
(36 answers)
Closed 2 years ago.
My ASP.NET application requires me to generate a huge number of random strings such that each contain at least 1 alphabetic and numeric character and should be alphanumeric on the whole.
For this my logic is to generate the code again if the random string is numeric:
public static string GenerateCode(int length)
{
if (length < 2 || length > 32)
{
throw new RSGException("Length cannot be less than 2 or greater than 32.");
}
string newcode = Guid.NewGuid().ToString("n").Substring(0, length).ToUpper();
return newcode;
}
public static string GenerateNonNumericCode(int length)
{
string newcode = string.Empty;
try
{
newcode = GenerateCode(length);
}
catch (Exception)
{
throw;
}
while (IsNumeric(newcode))
{
return GenerateNonNumericCode(length);
}
return newcode;
}
public static bool IsNumeric(string str)
{
bool isNumeric = false;
try
{
long number = Convert.ToInt64(str);
isNumeric = true;
}
catch (Exception)
{
isNumeric = false;
}
return isNumeric;
}
While debugging, it is working properly but when I ask it to create 10,000 random strings, its not able to handle it properly. When I export that data to Excel, I find at least 20 strings on an average that are numeric.
Is it a problem with my code or C#? - Mine.
If anyone's looking for code,
public static string GenerateCode(int length)
{
if (length < 2)
{
throw new A1Exception("Length cannot be less than 2.");
}
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var random = new Random();
var result = new string(
Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)])
.ToArray());
return result;
}
public static string GenerateAlphaNumericCode(int length)
{
string newcode = string.Empty;
try
{
newcode = GenerateCode(length);
while (!IsAlphaNumeric(newcode))
{
newcode = GenerateCode(length);
}
}
catch (Exception)
{
throw;
}
return newcode;
}
public static bool IsAlphaNumeric(string str)
{
bool isAlphaNumeric = false;
Regex reg = new Regex("[0-9A-Z]+");
isAlphaNumeric = reg.IsMatch(str);
return isAlphaNumeric;
}
Thanks to all for your ideas.
If you want to stick with the Guid as the generator, you could always validate using a Regex
This will only return true if at least one alpha is present
Regex reg = new Regex("[a-zA-Z]+");
Then just use the IsMatch method to see if your string is valid
That way you don't need the (IMHO rather ugly) try..catch around the Convert.
Update : I see your subsequent comment about actually making your code slower. Are you instantiating the Regex object only once, or every time that the test is being done? If the latter then this will be rather inefficient, and you should consider using a "lazy-loaded" property on your class, e.g.
private Regex reg;
private Regex AlphaRegex
{
get
{
if (reg == null) reg = new Regex("[a-zA-Z]+");
return reg;
}
}
Then just use AlphaRegex.IsMatch() in your method. I would expect this to make a difference.
use name space then using System.Linq; use normal string
check whether the string consist at lest one character or number.
using System.Linq;
string StrCheck = "abcd123";
check the string has characters ---> StrCheck.Any(char.IsLetter)
check the string has numbers ---> StrCheck.Any(char.IsDigit)
if (StrCheck.Any(char.IsLetter) && StrCheck.Any(char.IsDigit))
{
//statement goes here.....
}
sorry for the late reply ...
I didn't quite understand what you want in the string except letters (abc etc) - lets say numbers.
You can generate a random character as following:
Random r = new Random();
r.Next('a', 'z'); //For lowercase
r.Next('A', 'Z'); //For capitals
//or you can convert lowercase to capital:
char c = 'k' + ('A' - 'a');
If you want to create a string:
var s = new StringBuilder();
for(int i = 0; i < length; ++i)
s.Append((char)r.Next('a', 'z' + 1)); //Changed to char
return s.ToString();
Note: I don't know ASP.NET so much, so I just act like it's C#.
To answer your question strictly, using your existing code: there is a problem with your recursion logic, which can be avoided by not using recursion (there is absolutely no reason to use recursion in GenerateNonNumericCode). Do the following instead:
public static string GenerateNonNumericCode(int length)
{
string newcode = GenerateCode(length);
while (IsNumeric(newcode))
{
newcode = GenerateCode(length);
}
return newcode;
}
Other General Notes
Your code is very inefficient--throwing exceptions is expensive, so using try/catch in a loop is therefore slow and pointless. As others have suggested, regex makes more sense (System.Text.RegularExpressions namespace).
Is it a problem with my code or C#?
When in doubt, the problem is almost never C#.
So, I would change the code to this:
static Random r = new Random();
public static string GenerateNonNumericCodeFaster(int length) {
var firstLength = r.Next(0, length - 1);
var secondLength = length - 1 - firstLength;
return GenerateCode(firstLength)
+ (char) r.Next((int)'A', (int)'G')
+ GenerateCode(secondLength);
}
You can keep your GenerateCode function as is. Everything else you toss out. The idea here of course is, rather than testing if the string contains an alphabetic character, you just explicitly PUT one in. In my tests, using this code could generate 10,000 8 character strings in 0.0172963 seconds compared to your code which takes around 52 seconds. So, yeah, this is about 3000 times faster :)

Mutable String Editing in C# / .NET

I want to take and edit a string in-place in a .NET app. I know that StringBuilder allows me to do in-place appends, inserts, and replaces, but it does not allow an easy way of doing stuff like this:
while (script.IndexOf("#Unique", StringComparison.InvariantCultureIgnoreCase) != -1)
{
int Location = script.IndexOf("#Unique", StringComparison.InvariantCultureIgnoreCase);
script = script.Remove(Location, 7);
script = script.Insert(Location, Guid.NewGuid().ToString());
}
As there is no IndexOf in StringBuilder. Does anyone have an effective way to do in-place editing of textual information?
Edit #1:
Changed sample to make more obvious that each 'replace' needs to have a different result.
If your code really is this straightforward then why not just use one of the built-in Replace methods, either on string, StringBuilder or Regex?
EDIT FOLLOWING COMMENT...
You can replace each occurrence with a separate value by using one of the overloads of Regex.Replace that takes a MatchEvaluator argument:
string foo = "blah blah #Unique blah #Unique blah blah #Unique blah";
// replace each occurrence of "#Unique" with a separate guid
string bar = Regex.Replace(foo, "#Unique",
new MatchEvaluator(m => Guid.NewGuid().ToString()),
RegexOptions.IgnoreCase));
How many replacements will you be doing?
If its not four figures, then just accept the new string instances, you may be prematurely optimising...
Another solution... Split on "#uniqueID" then rejoin with a StringBuilder adding your seperator for each iteration.
How about StringBuilder "Replace" method:
StringBuilder script;
script.Replace("#Unique", GetGuidString());
StringBuilder is made so that you can easily add to it, but at the tradeoff that it's difficult to search in it - and especially, it's more difficult (i.e. slower) to index it.
If you need to modify some characters "in-place", it's best to do it on the resulting string.
But it's difficult to know from your question what is the right answer for you, my feeling is that you shouldn't be needing in-place replacement in a StringBuilder, and the problem is somewhere else/you do something else wrong.
User Dennis has provided an IndexOf extension method for StringBuilder. With this, you should be able to use StringBuilder in this manner.
Can you use a string split to do this efficiently?
Something like:
var sections = "a-#Unique-b-#Unique-c".Split(new string[] { "#Unique" }, StringSplitOptions.None);
int i;
StringBuilder builder = new StringBuilder();
for(i = 0; i < sections.Length - 1; i++)
{
builder.Append(sections[i]);
builder.Append(Guid.NewGuid().ToString());
}
builder.Append(sections[i]);
Console.WriteLine(builder.ToString());
Console.ReadKey(true);
complex but should be performant solution
public StringBuilder Replace(this StringBuilder sb, string toReplace, Func<string> getReplacement)
{
for (int i = 0; i < sb.Length; i++)
{
bool replacementFound = true;
for (int toReplaceIndex = 0; toReplaceIndex < toReplace.Length; toReplaceIndex++)
{
int sbIndex = toReplaceIndex + i;
if (sbIndex < sb.Length)
{
return sb;
}
if (sb[sbIndex] != toReplace[toReplaceIndex])
{
replacementFound = false;
break;
}
}
if (replacementFound)
{
string replacement = getReplacement();
// reuse the space of the toReplace string
for (int replacementIndex = 0; replacementIndex < toReplace.Length && replacementIndex < replacement.Length; replacementIndex++)
{
int sbIndex = replacementIndex + i;
sb[sbIndex] = replacement[i];
}
// remove toReplace string remainders
if (replacement.Length < toReplace.Length)
{
sb.Remove(i + replacement.Length, replacement.Length - toReplace.Length)
}
// insert chars not yet inserted
if (replacement.Length > toReplace.Length)
{
sb.Insert(i + toReplace.Length, replacement.ToCharArray(toReplace.Length, toReplace.Length - replacement.Length));
}
}
}
return sb;
}
use case
var sb = new StringBuilder(script);
script = sb.Replace("#Unique", () => Guid.NewGuid().ToString()).ToString();
You are going to need to use an unmanaged code block
As simple as declare a pointer to your string and manipulate it in memory.
Example
unsafe
{
char* ip;
ip = &to_your_string;
}

How to search a string in String array

I need to search a string in the string array. I dont want to use any for looping in it
string [] arr = {"One","Two","Three"};
string theString = "One"
I need to check whether theString variable is present in arr.
Well, something is going to have to look, and looping is more efficient than recursion (since tail-end recursion isn't fully implemented)... so if you just don't want to loop yourself, then either of:
bool has = arr.Contains(var); // .NET 3.5
or
bool has = Array.IndexOf(arr, var) >= 0;
For info: avoid names like var - this is a keyword in C# 3.0.
Every method, mentioned earlier does looping either internally or externally, so it is not really important how to implement it. Here another example of finding all references of target string
string [] arr = {"One","Two","Three"};
var target = "One";
var results = Array.FindAll(arr, s => s.Equals(target));
Does it have to be a string[] ? A List<String> would give you what you need.
List<String> testing = new List<String>();
testing.Add("One");
testing.Add("Two");
testing.Add("Three");
testing.Add("Mouse");
bool inList = testing.Contains("Mouse");
bool exists = arr.Contains("One");
I think it is better to use Array.Exists than Array.FindAll.
Its pretty simple. I always use this code to search string from a string array
string[] stringArray = { "text1", "text2", "text3", "text4" };
string value = "text3";
int pos = Array.IndexOf(stringArray, value);
if (pos > -1)
{
return true;
}
else
{
return false;
}
If the array is sorted, you can use BinarySearch. This is a O(log n) operation, so it is faster as looping. If you need to apply multiple searches and speed is a concern, you could sort it (or a copy) before using it.
Each class implementing IList has a method Contains(Object value). And so does System.Array.
Why the prohibition "I don't want to use any looping"? That's the most obvious solution. When given the chance to be obvious, take it!
Note that calls like arr.Contains(...) are still going to loop, it just won't be you who has written the loop.
Have you considered an alternate representation that's more amenable to searching?
A good Set implementation would perform well. (HashSet, TreeSet or the local equivalent).
If you can be sure that arr is sorted, you could use binary search (which would need to recurse or loop, but not as often as a straight linear search).
You can use Find method of Array type. From .NET 3.5 and higher.
public static T Find<T>(
T[] array,
Predicate<T> match
)
Here is some examples:
// we search an array of strings for a name containing the letter “a”:
static void Main()
{
string[] names = { "Rodney", "Jack", "Jill" };
string match = Array.Find (names, ContainsA);
Console.WriteLine (match); // Jack
}
static bool ContainsA (string name) { return name.Contains ("a"); }
Here’s the same code shortened with an anonymous method:
string[] names = { "Rodney", "Jack", "Jill" };
string match = Array.Find (names, delegate (string name)
{ return name.Contains ("a"); } ); // Jack
A lambda expression shortens it further:
string[] names = { "Rodney", "Jack", "Jill" };
string match = Array.Find (names, n => n.Contains ("a")); // Jack
At first shot, I could come up with something like this (but it's pseudo code and assuming you cannot use any .NET built-in libaries). Might require a bit of tweaking and re-thinking, but should be good enough for a head-start, maybe?
int findString(String var, String[] stringArray, int currentIndex, int stringMaxIndex)
{
if currentIndex > stringMaxIndex
return (-stringMaxIndex-1);
else if var==arr[currentIndex] //or use any string comparison op or function
return 0;
else
return findString(var, stringArray, currentIndex++, stringMaxIndex) + 1 ;
}
//calling code
int index = findString(var, arr, 0, getMaxIndex(arr));
if index == -1 printOnScreen("Not found");
else printOnScreen("Found on index: " + index);
In C#, if you can use an ArrayList, you can use the Contains method, which returns a boolean:
if MyArrayList.Contains("One")
You can check the element existence by
arr.Any(x => x == "One")
it is old one ,but this is the way i do it ,
enter code herevar result = Array.Find(names, element => element == "One");
I'm surprised that no one suggested using Array.IndexOf Method.
Indeed, Array.IndexOf has two advantages :
It allows searching if an element is included into an array,
It gets at the same time the index into the array.
int stringIndex = Array.IndexOf(arr, theString);
if (stringIndex >= 0)
{
// theString has been found
}
Inline version :
if (Array.IndexOf(arr, theString) >= 0)
{
// theString has been found
}
Using Contains()
string [] SomeArray = {"One","Two","Three"};
bool IsExist = SomeArray.Contains("One");
Console.WriteLine("Is string exist: "+ IsExist);
Using Find()
string [] SomeArray = {"One","Two","Three"};
var result = Array.Find(SomeArray, element => element == "One");
Console.WriteLine("Required string is: "+ result);
Another simple & traditional way, very useful for beginners to build logic.
string [] SomeArray = {"One","Two","Three"};
foreach (string value in SomeArray) {
if (value == "One") {
Console.WriteLine("Required string is: "+ value);
}
}

Categories