I'm very new to c# so please excuse my lack of knowledge. I'm just trying to check the following:
"CardNumberLength" = 16
"CardPINLength" = 3
"CardNameHasSpace" 0
I don't want to use an if else statement, is there another way?
The code:
public bool Validate()
{
CardNumberLength = Convert.ToString(GetCardNumber()).Length;
CardPINLength = Convert.ToString(GetCardPIN()).Length;
CardNameHasSpace = GetCardName().IndexOf(" ");
}
You could just return the boolean result:
return CardNumberLength == 16 && CardPINLength == 3 && CardNameHasSpace >= 0;
If you absolutely had to do this without if tests, you could mash them together in a return statement. It's just a different syntax to express the same logic. I probably wouldn't suggest doing this without if tests though.
public bool Validate()
{
return Convert.ToString(GetCardNumber()).Length == 16 //replaces CardNumberLength
&& Convert.ToString(GetCardPin()).Length == 3 // replaces CardPINLength
&& GetCardName().IndexOf(" ") < 1; // replaces CardNameHasSpace
}
public bool Validate()
{
int CardNumberLength = int.Parse(GetCardNumber().ToString().Length);
int CardPINLength = int.Parse(GetCardPIN().ToString().Length);
bool CardNameHasSpace = GetCardName().Contains(" ");
return CardNumberLength == 16 && CardPINLength == 3 && !CardNameHasSpace
}
using the .ToString() on an object is way better than Convert.ToString(), also you can check inside a string if it contains a certain string with the .Contains(string) function on a string.
public bool Validate()
{
CardNumberLength = Convert.ToString(GetCardNumber()).Length;
CardPINLength = Convert.ToString(GetCardPIN()).Length;
CardNameHasSpace = GetCardName().IndexOf(" ");
return CardNumberLength == 16 && CardPINLength == 3 && CardNameHasSpace > -1;
}
Or
public bool Validate()
{
CardNumberLength = Convert.ToString(GetCardNumber()).Length;
CardPINLength = Convert.ToString(GetCardPIN()).Length;
CardNameHasSpace = GetCardName().IndexOf(" ");
if (CardNumberLength != 16)
return false;
if (CardPINLength != 3)
return false;
if (CardNameHasSpace == -1)
return false;
return true;
}
Perhaps, this helps you :)
Related
I'm trying to know if a string contains a length between 5 and 10 and at the same time, 7-10 letters are in upper case. The idea is to detect if a message sent by a user is 70%-100% capped.
This is what I have tried so far:
bool IsMessageUpper(string input)
{
if (input.Length.Equals(5 <= 10) && (input.Take(7).All(c => char.IsLetter(c) && char.IsUpper(c))))
{
return true;
}
else
{
return false;
}
}
You can rewrite your method in this way
bool IsMessageUpper(string input)
{
int x = input.Length;
return x>=7 && x<= 10 && input.Count(char.IsUpper) >= 7;
}
You can also add some safety checks to handle undesidered inputs
bool IsMessageUpper(string input)
{
int x = (input ?? "").Length;
return x>=7 && x<= 10 && input.Count(char.IsUpper) >= 7;
}
I've written a recursion that checks if a string is a palindrome :
public static bool IsPalindrome(string value)
{
if ( value == null )
return false;
if ( value.Length == 0 )
return true;
return isPalindrome(value, 0, value.Length - 1);
}
private static bool isPalindrome(string value, int startChar, int endChar)
{
if ( value[startChar] != value[endChar] )
return false;
if ( startChar >= endChar )
return true;
return isPalindrome(value, startChar + 1, endChar - 1);
}
However I tried to find a way to do the same algorithm without using an auxiliary method that does the recursion (isPalindrome(.. , .. , ..)) however I still need the call of isPalindrome(...) .
How can I combine the two functions into one , where the recursion algorithm wouldn't make a call to any additional functions ?
Would replacing the separate method with an anonymous one be acceptable:
public static bool IsPalindrome(string value)
{
if (value == null)
return false;
if (value.Length == 0)
return true;
Func<string, int, int, bool> ip = null;
ip = (v, sc, ec) =>
{
if (v[sc] != v[ec])
return false;
if (sc >= ec)
return true;
return ip(v, sc + 1, ec - 1);
};
return ip(value, 0, value.Length - 1);
}
Here:
public static bool IsPalindrome(string value)
{
if ( value == null )
return false;
if ( value.Length <= 1 )
return true;
if ( value[0] != value[value.Length - 1] )
return false;
return IsPalindrome(value.Substring(1,value.Length - 2));
}
Performance would suck though... because this allocates n/2 strings...
You could do something a little smarter with an array window wrapper... But i don't recall .Net having those built in...
Option 2 :
public static bool IsPalindrome(IEnumerable<char> value)
{
if (value == null)
return false;
if (value.Count() <= 1)
return true;
if (value.First() != value.Last())
return false;
return IsPalindrome(value.Skip(1).Take(value.Count() - 1));
}
This has some hope of better performance... depending on how LINQ does specializations...
Tested the second one, and its dreadfully slow....
How about using a while-loop:
using System;
public class Program
{
public static void Main()
{
Console.WriteLine(IsPalindrome("TEST"));
Console.WriteLine(IsPalindrome("TESTSET"));
}
public static bool IsPalindrome(string value)
{
if ( value == null )
return false;
if ( value.Length == 0 )
return true;
int startChar = 0;
int endChar = value.Length - 1;
while(value[startChar] == value[endChar] && startChar < endChar)
{
startChar++;
endChar--;
if(startChar >= endChar) return true;
}
return false;
}
}
Output:
False
True
I like your recursive solution much more though.
EDIT
Or... you could do it with one statement:
public static bool IsPalindrome(string value)
{
if ( value == null )
return false;
return value == new String(value.ToCharArray().Reverse().ToArray());
}
EDIT
And another solution using a for-loop. It is similar to doing a reverse and then compare.
public static bool IsPalindrome(string value)
{
if ( value == null )
return false;
for(int i = 0, j = value.Length - 1; i < j; i++, j--) {
if(value[i] != value[j]) return false;
}
return true;
}
I would suggest something like this:
public static bool IsPalindrome(string value)
{
if ( value == null )
return false;
if ( value.Length == 0 )
return true;
int i=0;
bool _cont = true;
while(_cont){
if ( value[startChar+i] != value[endChar-i] ){
_cont = false;
return false;
if ( (startChar+i) >= (endChar-i) ){
i++;
}
else{
_cont = false;
return true;
}
}
}
public static int isPalindrome(char[] String)
{
if (String.Length == 0 || String.Length == 1)
return 1;
if (String[0] != String[String.Length - 1])
return 0;
return Convert.ToUInt32(isPalindrome(String);
}
I am not able to make it as instance method i am getting problems so please help me how to make it as dynamic
This should work:
public static int isPalindrome(char[] String)
{
string smallerString = String.ToString().Substring(1, String.Length - 1);
if (String.Length == 0 || String.Length == 1)
return 1;
if (String[0] != String[String.Length - 1])
return 0;
return Convert.ToInt32(isPalindrome(smallerString.ToCharArray()));
}
Without changing your types and return values
public static int isPalindrome(char[] str)
{
if (str.Length == 0 || str.Length == 1)
return 1;
if (str[0] != str[str.Length - 1])
return 0;
return isPalindrome(str.Skip(1).Take(str.Length-2).ToArray());
}
You are passing the same value to isPalindrome again and again. You can try something like the following (note I've used string in the example below):
private static bool isPalindrome(string s)
{
if(s.Length == 1 || s.Length == 0)
return true;
if(s[0] != s[s.Length -1])
return false;
return isPalindrome(s.SubsString(1, s.Length -2));
}
I think it could be very easy implemented.
public static bool IsPalindrome(String text)
{
if(string.IsNullOrWhiteSpace(text))
return false;
char[] arr = text.ToCharArray();
Array.Reverse(arr);
var reversedText = new string(arr);
return string.Equals(text, reversedText, StringComparison.OrdinalIgnoreCase);
}
I am trying to write a function to control if the parenthesis included in a stringare balanced or not.
I have written the following function:
public bool IsBalanced(string input)
{
//last condition, gets out
if (string.IsNullOrEmpty(input)) return true;
int numOpen = 0;
bool opened = false;
foreach (char c in input)
{
if (char.ToUpperInvariant(c) =='(')
{
opened = true;
numOpen+=1;
}
if (char.ToUpperInvariant(c) == ')')
{
if (opened)
{
numOpen-=1;
opened = numOpen > 0;
}
else
return false; //incorrect position parentheses, closes but not opened
}
}
return numOpen == 0;
}
I wanted to change it to a recursive function, but have not been able to do so. Could anyone give a hint how to do it?
Well, your algorithm is not pretty. Here is a better one
int check = 0;
foreach (var c in input)
{
if (c == '(') {
check++;
} else if (c == ')') {
check--;
}
if (check < 0) {
return false; // error, closing bracket without opening brackets first
}
}
return check == 0; // > 0 error, missing some closing brackets
To make it (algorithm of checking for balanced brackets) recursive you can go with following
bool IsBalanced(string input)
{
var first = input.IndexOf('('); // first opening bracket position
var last = input.LastIndexOf(')'); // last closing bracket position
if (first == -1 && last == -1)
return true; // no more brackets - balanced
if (first == -1 && last != -1 || first != -1 && last == -1)
return false; // error - one of brackets is missing
if (first > last)
return false; // error - closing bracket is BEFORE opening
return IsBalanced(input.Substring(first, last - first)); // not sure, might need to tweak it, parameter should be without first and last bracket (what is inside)
}
This simply remove first opening brackets and last closing bracket and pass what is left as parameter (recursively) until one of the end conditions is met.
The basic idea is to take a variant (numOpen in this case) as an argument.
Here is my code:
public bool IsBalancedRec(string input, int numOpen = 0)
{
if (numOpen < 0)
return false;
if (string.IsNullOrEmpty(input))
return numOpen == 0;
char c = input[0];
string rest = input.Substring(1);
if (c == '(')
return IsBalancedRec(rest, numOpen + 1);
else if (c == ')')
return IsBalancedRec(rest, numOpen - 1);
else
return IsBalancedRec(rest, numOpen);
}
And call this like IsBalancedRec("so(m(eth)ing)").
Implement with stack:
Stack myStak = new Stack();
public bool IsBalanced(string input)
{
if (input.ToArray().Count() != 0)
{
if(input.ToArray()[0] == '(')
{
myStak.Push('(');
}
else if(input.ToArray()[0] == ')')
{
if (myStak.Count != 0)
myStak.Pop();
else
{
//not balanced
return false;
}
}
return IsBalanced(input.Substring(1));
}
else
{
if (myStak.Count == 0)
{
//balanced
return true;
}
else
{
//not balanced
return false;
}
}
}
public static bool IsBalanced(string input)
{
int numOpen = 0;
while(input != "")
{
char c = input[0];
input = input.Substring(1);
numOpen = c == '(' ? (numOpen + 1) : (c == ')' ? (numOpen - 1) : numOpen);
}
return numOpen == 0;
}
// count no of left and right bracket or parenthesis and check counts
var InputStr= str.ToCharArray();
int left = 0;
int right = 0;
foreach (char item in InputStr)
{
if(item == '(')
{
left ++;
} else if(item == ')')
{
right ++;
}
}
if(right == l)
{
return "1";
}
return "0";
}
Probably a pretty newb question but here we go.
I am quite new to this and right now i have reached my first logic problem i guess.
I've created a class + method which is supposed to return me a Int32 value and it returns something that is, atleast in my eyes, unreachable. I also dont want this value to be returned.
Here's the code:
public static Int32 SetInterval(ConsoleKeyInfo cki)
{
if (cki.Key == ConsoleKey.D1 || cki.Key == ConsoleKey.D2 || cki.Key == ConsoleKey.D3 || cki.Key == ConsoleKey.D4 || cki.Key == ConsoleKey.D5 || cki.Key == ConsoleKey.D6)
{
if (cki.Key == ConsoleKey.D1)
{
return 10000;
}
else if (cki.Key == ConsoleKey.D2)
{
return 20000;
}
else if (cki.Key == ConsoleKey.D3)
{
return 30000;
}
else if (cki.Key == ConsoleKey.D4)
{
return 45000;
}
else if (cki.Key == ConsoleKey.D5)
{
return 60000;
}
else if (cki.Key == ConsoleKey.D6)
{
return 120000;
}
}
else
{
SetInterval(Console.ReadKey());
}
return 50;
}
And here is how i execute it within my main class:
static int interval;
interval = DefineInterval.SetInterval(Console.ReadKey());
Console.WriteLine("");
Console.WriteLine(interval.ToString());
So whats happening now is:
If i press one of the 6 numbers correctly without pressing any other key before, its just fine. The output is normal and as it's supposed to be.
Then again, when i press, for example "a6" on my Keyboard all i get is:
"
a6
50
"
Any ideas? Also probably not the best way to do such a thing.
The recursive call to SetInterval in the else block doesn't do anything with the return value. What you want is this:
public static Int32 SetInterval(ConsoleKeyInfo cki)
{
if (cki.Key == ConsoleKey.D1)
{
return 10000;
}
else if (cki.Key == ConsoleKey.D2)
{
return 20000;
}
else if (cki.Key == ConsoleKey.D3)
{
return 30000;
}
else if (cki.Key == ConsoleKey.D4)
{
return 45000;
}
else if (cki.Key == ConsoleKey.D5)
{
return 60000;
}
else if (cki.Key == ConsoleKey.D6)
{
return 120000;
}
else
{
return SetInterval(Console.ReadKey());
}
}
Note that I also moved the unnecessary if statement surrounding the first else if chain.
public static Int32 SetInterval(ConsoleKeyInfo cki)
{
if (cki.Key == ConsoleKey.D1 || cki.Key == ConsoleKey.D2 || cki.Key == ConsoleKey.D3 || cki.Key == ConsoleKey.D4 || cki.Key == ConsoleKey.D5 || cki.Key == ConsoleKey.D6)
{
if (cki.Key == ConsoleKey.D1)
{
return 10000;
}
else if (cki.Key == ConsoleKey.D2)
{
return 20000;
}
else if (cki.Key == ConsoleKey.D3)
{
return 30000;
}
else if (cki.Key == ConsoleKey.D4)
{
return 45000;
}
else if (cki.Key == ConsoleKey.D5)
{
return 60000;
}
else if (cki.Key == ConsoleKey.D6)
{
return 120000;
}
}
else
{
return SetInterval(Console.ReadKey());
}
}
You are recursively calling your method. When you give correct input, it goes fine.
Else it goes to get correct input, and after that correct input it returns the default value from the first call of the method.
Solution:
Just remove the return 50 and set:
else
{
return SetInterval(Console.ReadKey());
}
Quick question- why would you press "a6" ? is it by mistake and you want this to be read as just 6 by your program and move on or is there a different reason behind it? If that is the reason then you need to remove the return 50 and place return SetInterval(Console.ReadKey()) in else.