I actually tried to make a StringToASCII function from scratch in c#.
I get the input from _myString and this is the code :
public void convertToASCII() {
//A-Z --> 65-90
//a-z --> 97-122
//0-9 --> 48-57
//Space --> 32
int[] returnString = new int[_myString.Length];
int iTableau = 0;
char iAZ = 'A';
char iaz = 'a';
char i09 = '0';
char iSpace = ' ';
for(int i = 0; i < _myString.Length; i++)
{
if(_myString[i] >= 65 && _myString[i] <= 90 || _myString[i] >= 97 && _myString[i] <= 122 || _myString[i] >= 48 && _myString[i] <= 57 || _myString[i] == 32)
{
while(iAZ < 90 || iaz < 122 || iaz < 122 || i09 < 57 || _myString[i] == 32)
{
if(_myString[i] == iAZ && iAZ >= 'A' && iAZ <= 'Z')
{
returnString[iTableau] = iAZ;
iTableau++;
iAZ--;
}
else
{
iAZ++;
}
if(_myString[i] == iaz && iaz >= 'a' && iaz <= 'z')
{
returnString[iTableau] = iaz;
iTableau++;
iaz--;
}
else
{
iaz++;
}
if(_myString[i] == i09 && i09 >= '0' && i09 <= '9')
{
returnString[iTableau] = i09;
iTableau++;
i09--;
}
else
{
i09++;
}
if(_myString[i] == iSpace)
{
returnString[iTableau] = iSpace;
iTableau++;
}
}
}
}
_myString = "";
for (int i = 0; i < returnString.Length; i++)
{
_myString += returnString[i];
}
}
I also tried this kind of function which it works, but i would like to make one who checks only chars from A-Z and a-z and 0-9 and space.
Same thing as the first function, i take the input from a global string variable called "_myString".
public void convertToASCII()
{
string asciiChar;
string returnString = "";
foreach (char c in _myString)
{
asciiChar= ((int)(c)).ToString();
returnString += " " + asciiChar;
}
_myString = returnString;
}
This is actually relatively simple:
public string StringToLettersOrNumbersOrSpace(string input)
{
var sb = new StringBuilder();
for (int i = 0; i < input.Length; i++)
{
if (Char.IsLetterOrDigit(input[i]) || input[i] == ' ')
{
sb.Append(input[i]);
}
}
return sb.ToString();
}
First, you'll want to use StringBuilder instead of continuously appending to a string variable. Strings in C# are immutable, meaning that they can't be changed after they've been created, so doing something like string s1 = "aaa"; s1 += "bbb"; will actually create an entirely new string instead of just adding to the original. StringBuilder, on the other hand, is mutable, so you don't need to worry about reallocating a bunch of strings every time you want to concatenate strings (which gets progressively slower and slower as the string gets bigger).
Second, you can use Char.IsLetterOrDigit instead of using comparisons. The method takes a char as input and returns true if the character is a letter (uppercase or lowercase) or a number. This maps directly to your desired range a-z, A-Z, and 0-9. Since you also care about spaces, though, you will have to manually check for that.
Related
How to write a code to count total no of digits, alphabets and special characters in mettl platform
how to return the output in above code
how to use return statement in below code
public string countstring(string input1)
{
int digits, alphabet, specialcharacters, i = 0;
int L = input1.Lenght;
for(i = 0;i <= L; i++)
{
if((input1[i] >= 'a' && input1[i] <= 'z') || (input1[i] >= 'A' && input1[i] <= 'Z'))
{
alphabet++;
}
else if (input1[i] >= '0' && input1[i] <= '9')
{
digits++;
}
else
{
specialcharacters++;
}
}
}
You have to return multiple values using a tuple
public static (int, int, int) count(string input) {
int digits = 0;
int alphabet = 0;
int special = 0;
foreach (var c in input) {
if (char.IsDigit(c)) {
digits++;
}
else if (char.IsLetter(c)) {
alphabet++;
}
else {
special++;
}
}
return (digits, alphabet, special);
}
public static class Inova
{
public static bool IsPangram(string str)
{
int compteur = 26;
for (int i = 0; i <= str.Length; i++)
{
if (('A' <= str[i] && str[i] <= 'Z') || ('a' <= str[i] && str[i] <= 'z'))
{
for (int j = str[i + 1]; j <= str.Length; j++)
{
if (compteur != 0 && str[i] != str[j])
{
compteur = compteur - 1;
}
}
}
if (compteur == 0)
{
return true;
}
else
{
return false;
}
}
}
}
There are multiple things incorrect:
for (int j = str[i + 1]; j <= str.Length; j++)
this does not do what you think, it will convert the next char to an int, you want to loop all letters until end, beginning from the current letter + 1.
The if ... else belong to the end of the method, outside of the loop, otherwise you return false after the first iteration in the for-loop
So you want to know if it's a perfect pangram? First we need to say what a pangram is: a sentence containing every letter of the alphabet. It seems you want to check if it's even a perfect pangram, so every letter should appear exactly once. Here is a method not using any fancy LINQ(which might not be allowed) that supports perfect/imperfect pangrams:
public static class Inova
{
private const string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static bool IsPangram(string str, bool mustBePerfect)
{
HashSet<char> remaingLetters = new HashSet<char>(alphabet);
foreach (char c in str)
{
char letter = char.ToUpperInvariant(c);
if (!alphabet.Contains(letter)) continue;
bool repeatingLetter = !remaingLetters.Remove(letter);
if (mustBePerfect && repeatingLetter)
{
return false; // already removed
}
}
return remaingLetters.Count == 0;
}
}
Usage:
bool isPangram = Inova.IsPangram("abcdefghijklmnopqrstuvwxyZZ", false);
Since z appears twice this method returns false for perfect and true for not perfect.
Demo: https://dotnetfiddle.net/gEXuvG
Side-note: i wanted to keep it simple, if you want you can still improve it. You can return true in the loop: if(!mustBePerfect && remaingLetters.Count == 0) return true.
I would check for existence of each letter in the string, so
public static bool IsPangram(string str) {
str = str.ToLower();
for (int i = 0; i < 26; i++) {
char c = Convert.ToChar(i + 97);
if (!str.Contains(c)) {
return false;
}
}
return true;
}
Console.WriteLine(IsPangram("hello world"));
Console.WriteLine(IsPangram("abcdefghi jkl mno pqrstuvwxyz"));
// output:
False
True
I'm working on a program that encodes and decodes letters to numbers. I have the Encoding properly built but the decoding is giving me problems. I'm using int to char conversions with the ASCII table as the key. It doesn't seem like the conversion logic for the decoding is right but I really have no idea how to fix it. This is my first time using this conversion method so I still don't fully understand it.
*edit This is on a windows form app that has three buttons and two text boxes. Encode is one button, and you type in a sentence and it outputs in in numbers for each letter. Decode is another but it does the opposite type in numbers and get words. the third button is clear so thats not important. Sorry I left this out of the initial question.
class LetterCodeLogic
{
public static string Encode(string msg)
{
string result = "";
string m = msg.ToUpper();
char c;
int x;
for(int i = 0; i < m.Length; i++)
{
c = Convert.ToChar(m[i]);
x = c;
if (x == 32)
{
x = 0;
}
else
{
x -= 64;
if (x < 1 || x > 26)
{
x = 99;
}
}
result += x.ToString() + " ";
}
return result;
}
public static string Decode(string msg)
{
string result = "";
string[] nums = msg.Split(',');
char c;
int x;
for (int i = 0; i < msg.Length; i++)
{
x = Convert.ToChar(msg[i]);
c = (char)x;
if (c == 0)
{
c = (char)32;
}
else
{
c -= (char)64;
if (c < 65 || c > 90)
{
c = (char)35;
}
}
result += c.ToString() + " ";
}
return result;
}
}
I find problems like this are far easier when you break them into parts. First, write functions that convert a single character to a number or vice versa.
static public byte Encode(char c)
{
if (c == ' ') return 0;
if (c >= 'A' && c <= 'Z') return (byte)(c - 'A' + 1);
return 99;
}
static public char Decode(byte n)
{
if (n == 0) return ' ';
if (n >= 1 && n <= 27) return (char)(n + 'A' - 1);
return '#';
}
Now the functions you need are very easy to write:
static public string Encode(string stringInput)
{
return string.Join(" ", stringInput.Select(Encode).Select( b => b.ToString() ));
}
static public string Decode(string numericInput)
{
return new string(numericInput.Split(' ').Select( n => byte.Parse(n)).Select(Decode).ToArray());
}
I am only able to encrypt, but i do not how to decrypt. Someone please help. Do I have to declare a bool variable?
Or is that any other better way to do it?
string UserInput = "";
int shift;
Shift OBSHIFT = new Shift();
Console.Write("\nType a string to encrypt:");
UserInput = Console.ReadLine();
Console.Write("How many chars would you like to shift?: ");
shift = int.Parse(Console.ReadLine());
Console.WriteLine("\nApplying Caesar cipher ... ");
Console.Write("Your encrypted string is: ");
Console.WriteLine(OBSHIFT.Cshift(UserInput, shift));
Console.Read();
}
}
class Shift
{
public string Cshift(string str, int shift )
{
string UserOutput = "";
char[] A = null;
A = str.ToCharArray();
int temp;
for (int i = 0; i < str.Length; i++)
{
char c = A[i];
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
{
temp = (int)(A[i] + shift);
if ((c >= 'A' && c <= 'Z' && temp > 'Z') || (c >= 'a' && c <= 'z' && temp > 'z'))
temp = temp - 26;
else
temp = (int)(A[i] + (shift));
}
else
temp = c;
UserOutput += (char)temp;
}
return UserOutput;
}
}
}
}
Talking about Caesar cipher, you can simply negate the shift and get the original string.
I.e., cshift(cshift(string, x), -x) == string.
Using your Shift class:
int sh = 17;
string original = "abcdefgh";
string encrypted = shift.Cshift(original, sh);
string decrypted = shift.Cshift(shifted, -sh);
Console.WriteLine(decrypted == original); // true
For convenience, you can create a method Decrypt, which will do this:
class Shift
{
public string Encrypt(string originalString, int shift)
{
string userOutput = "";
char[] a = originalString.ToCharArray();
for (int i = 0; i < originalString.Length; i++)
{
char c = a[i];
int temp;
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
{
temp = (int)(a[i] + shift);
if ((c >= 'A' && c <= 'Z' && temp > 'Z') || (c >= 'a' && c <= 'z' && temp > 'z'))
temp = temp - 26;
else
temp = (int)(a[i] + (shift));
}
else
temp = c;
userOutput += (char)temp;
}
return userOutput;
}
public string Decrypt(string cipherString, int shift)
{
return Encrypt(cipherString, -shift);
}
}
Note that I have also done some little code improvements like:
combined declaration and assignment of A
moved temp into the inner scope
gave the proper names to the local variables (lower-case)
My initial code is 'A0AA' and I need a code/function in C# that will increment it until it goes to 'Z9ZZ'.
for example.
first code is 'D9ZZ'
the next code should be 'E0AA'
sorry maybe my example is quite confusing.. here's another example.. thanks.
first code is 'D9AZ'
the next code should be 'D9BA'
string start = "A9ZZ";
int add = 1;
string next = String.Concat(start.Reverse().Select((x,i) =>
{
char first = i == 2 ? '0' : 'A';
char last = i == 2 ? '9' : 'Z';
if ((x += (char)add) > last)
{
return first;
}
else
{
add = 0;
return x;
}
})
.Reverse());
This should fix it.
private static IEnumerable<string> Increment(string value)
{
if (value.Length != 4)
throw new ArgumentException();
char[] next = value.ToCharArray();
while (new string(next) != "Z9ZZ")
{
next[3]++;
if (next[3] > 'Z')
{
next[3] = 'A';
next[2]++;
}
if (next[2] > 'Z')
{
next[2] = 'A';
next[1]++;
}
if (next[1] > '9')
{
next[1] = '0';
next[0]++;
}
yield return new string(next);
}
}
Example of calling this code:
IList<string> values = Increment("A0AA").Take(100).ToList();
foreach (var value in values)
{
Console.Write(value + " ");
}
Here's a pretty clean solution that checks every character starting at the end:
public SomeMethod()
{
var next = Increment("A2CZ"); // A2DZ
}
public string Increment(string code)
{
var arr = code.ToCharArray();
for (var i = arr.Length - 1; i >= 0; i--)
{
var c = arr[i];
if (c == 90 || c == 57)
continue;
arr[i]++;
return new string(arr);
}
return code;
}