C# build the if conditions at runtime - c#

I have nested if else structure, more or less doing the same thing.
simply it's a single if(A && B && C)
but I have flag D and E for condition A and C respectively.
That means if D is false, A should be disappear and not evaluated. It's same for C not be evaluated if E if false.
Now, my code now is similar as follows:
if (D){
if (A && B){
if (E){
if (C)
{ Do Something }
} else { Do Something else}
}
} else
if (B) {
if (E){
if (C)
{ Do Something }
} else { Do Something else}
}
}
Is any easy way to reduce this complicated structure to several lines of code?

Since both branch actions are the same you could essentially write:
if ((D && A && B) || (!D && B))
{
if (E && C)
{
DoSomething();
}
else
{
DoSomethingElse();
}
}
Hopefully your variables are more readable than A,B,C etc :)

I have tested it in c since I am on unix console right now. However, logical operators work the same way for c#. following code can also be used to test the equivalance.
#include<stdio.h>
void test(int,int,int,int,int);
void test1(int,int,int,int,int);
int main()
{
for(int i =0 ; i < 2 ; i++)
for(int j =0 ; j < 2 ; j++)
for(int k =0 ; k < 2 ; k++)
for(int l =0 ; l < 2 ; l++)
for(int m =0 ; m < 2 ; m++)
{
printf("A=%d,B=%d,C=%d,D=%d,E=%d",i,j,k,l,m);
test(i,j,k,l,m);
test1(i,j,k,l,m);
printf("\n");
}
return 0;
}
void test1(int A, int B, int C, int D, int E)
{
if( B && (!D || A) && (!E || C))
{
printf("\n\ttrue considering flags");
}
else
{
printf("\n\tfalse considering flags");
}
}
void test(int A, int B, int C, int D, int E)
{
if(D)
{
if( A && B)
if(E)
if(C)
{
printf("\n\ttrue considering flags");
}
else
{
printf("\n\tAB !C DE");
}
}
else
{
if( B)
if(E)
if(C)
{
printf("\n\t!D --ignore A-- BC E");
}
else
{
printf("\n\tfalse considering flags");
}
}
}

Related

C# code : count total no of digits, alphabets and special characters in mettl platform

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);
}

I need to check if a string is a pangram string or not is my code correct?

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

Program that converts numbers to letters both ways

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());
}

Is there any better way to compare these values in C#?

I have method for comparing values like this:
protected bool CompareValues(string a="", int b=0, string c="", int d=0, string e="", int f=0)
{
int counter = 0;
if(int.Parse(a) > b)
{
counter++;
}
if(int.Parse(c) > d)
{
counter++;
}
if(counter > 1)
{
counter = 1;
}
if(int.Parse(e) > f)
{
counter++;
}
if(counter > 1)
{
return true;
}
else
{
return false;
}
}
It works fine for me, but I am can't stand without thinking about some improvement if possible. Any suggestion would be appreciate.
If you need to perform n-many comparisons of the form
(int.Parse(a1) > b1 || int.Parse(a2) > b2 || ... || int.Parse(aK) > bK) && int.Parse(aN) > bN
You can make a method that just accepts a set of pairs of values to compare
protected bool CompareValues(params Tuple<string, int>[] comparisons)
{
if(ReferenceEquals(comparisons, null))
{
throw new ArgumentNullException("comparisons");
}
if(comparisons.Length < 1)
{
throw new ArgumentException("At least one pair to compare must be specified");
}
var atLeastOneComparisonSucceeded = comparisons.Length == 1;
for(var i = 0; !atLeastOneComparisonSucceeded && i < comparisons.Length - 1; ++i)
{
atLeastOneComparisonSucceeded = int.Parse(comparisons[i].Item1) > comparisons[i].Item2;
}
var lastIndex = comparisons.Length - 1;
return atLeastOneComparisonSucceeded && int.Parse(comparisons[lastIndex].Item1) > comparisons[lastIndex].Item2;
}
Usage:
var result = CompareValues(new Tuple<string, int>("5", 2),
new Tuple<string, int>("3", 1),
new Tuple<string, int>("1", 2));
If you only ever need 3 pairs of values (as in your original post), you could provide overloads for the method that provided appropriate default values, like this
protected static bool CompareValues(string a, int b)
{
return CompareValues(a, b, "1", 0);
}
protected static bool CompareValues(string a, int b, string c, int d)
{
return CompareValues(a, b, c, d, "1", 0);
}
protected static bool CompareValues(string a, int b, string c, int d, string e, int f)
{
return ((int.Parse(a) > b || int.Parse(c) > d) && int.Parse(e) > f);
}
Of course, the arguments passed down from the overloads must be chosen such that the semantics are appropriate.
I am not sure in the middle why you reset counter to 1, however this is what I understood
if((int.Parse(a) > b || int.Parse(c) > d) && int.Parse(e) > f)
{
return true;
}
else
{
return false;
}
It looks like you want:
return (int.Parse(a) > b || int.Parse(c) > d) && int.Parse(e) > f;
I'm not sure but is this what you are trying to do?
return ( ( int.Parse(a) > b || int.Parse(c) > d ) && int.Parse(e) > f);

Run length decoder in C#

Is it possible that anyone around here might have a run-length DECODER in C#? I'm in real need of said code. Thanks.
using System;
class RLDEC
{
static void Main()
{
int t = int.Parse(Console.ReadLine());
for (int k = 0; k < t; k++)
{
string s = Console.ReadLine();
s = runLengthDecoder(s);
Console.WriteLine(s);
}
}
static string runLengthDecoder(string s)
{
string d = ""; // decoded string
int cv; // current value
for(int k = 0; k < s.Length; k++)
{
cv = Convert.ToInt32(s[k]) - 48;
if (k + 1 < s.Length && cv != 1 && cv >= 2 && cv <= 9)
{
for(int v = 0; v < cv; v++)
d += s[k+1];
}
if (cv == 1)
{
int z = k + 1;
while(k < s.Length && z < s.Length && Convert.ToInt32(s[z]) - 48 != 1)
{
d += s[z];
z++;
k++;
}
k++;
}
}
return d;
}
}
It's hard to solve this without the specification for your encoding, but in this code
if (k + 1 < s.Length && cv != 1 && cv >= 2 && cv <= 9)
{
for(int v = 0; v < cv; v++)
d += s[k+1];
}
I would expect k to be incremented before leaving the if block.
Also, I would expect that the next if (cv==1) is an else if instead.
In that cv==1 block, I think you should just process then next character and let the outer for loop do its work.
I also don't understand how that block could work at all

Categories

Resources