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);
}
Related
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 :)
i'm trying to make a class that contains 4 functions: isLong, isDouble, stringToLong, and stringToDouble. I am trying to do this without using a TryParse function. Ideally this class would receive a string and return the appropriate type (bool, bool, long, and double) in respective order.
For instance if i enter the number 100000 it returns True (bool) for isLong.
Below is an example of how i did isLong but i am having difficulty trying to do the same for isDouble for receiving decimals and for both stringToLong/stringToDouble.
public static bool isLong(string s)
{
bool ret = true;
int i;
s = s.Trim();
if (s[0] == '-')
{
i = 1;
}
else
{
i = 0;
}
for (; (i < s.Length); i = i + 1)
{
ret = ret && ((s[i] >= '0') && (s[i] <= '9'));
}
return (ret);
}
You could use MinValue and MaxValue properties for check numeric types, for instance you could define a method like this:
public bool IsLong(decimal value)
{
return value >= long.MinValue && value <= long.MaxValue && value == (long)value;
}
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;
}
}
}
Please tell me how to validate GUID in .net and it is unique for always?
Guid's are unique 99.99999999999999999999999999999999% of the time.
It depends on what you mean by validate?
Code to determine that a Guid string is in fact a Guid, is as follows:
private static Regex isGuid =
new Regex(#"^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$", RegexOptions.Compiled);
internal static bool IsGuid(string candidate, out Guid output)
{
bool isValid = false;
output = Guid.Empty;
if(candidate != null)
{
if (isGuid.IsMatch(candidate))
{
output=new Guid(candidate);
isValid = true;
}
}
return isValid;
}
2^128 is a very, very large number. It is a billion times larger than the number of picoseconds in the life of the universe. Too large by a long shot to ever validate, the answer is doomed to be "42". Which is the point of using them: you don't have to. If you worry about getting duplicates then you worry for the wrong reason. The odds your machine will be destroyed by a meteor impact are considerably larger.
Duck!
Here's a non-Regex answer that should be pretty fast:
public static bool IsHex(this char c)
{
return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
}
public static bool IsGuid(this string s)
{
// Length of a proper GUID, without any surrounding braces.
const int len_without_braces = 36;
// Delimiter for GUID data parts.
const char delim = '-';
// Delimiter positions.
const int d_0 = 8;
const int d_1 = 13;
const int d_2 = 18;
const int d_3 = 23;
// Before Delimiter positions.
const int bd_0 = 7;
const int bd_1 = 12;
const int bd_2 = 17;
const int bd_3 = 22;
if (s == null)
return false;
if (s.Length != len_without_braces)
return false;
if (s[d_0] != delim ||
s[d_1] != delim ||
s[d_2] != delim ||
s[d_3] != delim)
return false;
for (int i = 0;
i < s.Length;
i = i + (i == bd_0 ||
i == bd_1 ||
i == bd_2 ||
i == bd_3
? 2 : 1))
{
if (!IsHex(s[i])) return false;
}
return true;
}
You cannot validate GUID's uniqueness. You just hope it was generated with a tool that produces unique 16 bytes. As for validation, this simple code might work (assuming you are dealing with GUID's string representation:
bool ValidateGuid(string theGuid)
{
try { Guid aG = new Guid(theGuid); }
catch { return false; }
return true;
}
If you're looking for a way to determine if it's the format of the actual .Net Guid type, take a look at this article. A quick regex does the trick.
this question was already discussed in this post. You may find more interesting details
In .net 4, you can use this extension method
public static class GuidExtensions
{
public static bool IsGuid(this string value)
{
Guid output;
return Guid.TryParse(value, out output);
}
}
i wrote a extension for this
public static bool TryParseGuid(this Guid? guidString)
{
if (guidString != null && guidString != Guid.Empty)
{
if (Guid.TryParse(guidString.ToString(), out _))
{
return true;
}
else
return false;
}
return false;
}
I am trying to truncate some long text in C#, but I don't want my string to be cut off part way through a word. Does anyone have a function that I can use to truncate my string at the end of a word?
E.g:
"This was a long string..."
Not:
"This was a long st..."
Try the following. It is pretty rudimentary. Just finds the first space starting at the desired length.
public static string TruncateAtWord(this string value, int length) {
if (value == null || value.Length < length || value.IndexOf(" ", length) == -1)
return value;
return value.Substring(0, value.IndexOf(" ", length));
}
Thanks for your answer Dave. I've tweaked the function a bit and this is what I'm using ... unless there are any more comments ;)
public static string TruncateAtWord(this string input, int length)
{
if (input == null || input.Length < length)
return input;
int iNextSpace = input.LastIndexOf(" ", length, StringComparison.Ordinal);
return string.Format("{0}…", input.Substring(0, (iNextSpace > 0) ? iNextSpace : length).Trim());
}
My contribution:
public static string TruncateAtWord(string text, int maxCharacters, string trailingStringIfTextCut = "…")
{
if (text == null || (text = text.Trim()).Length <= maxCharacters)
return text;
int trailLength = trailingStringIfTextCut.StartsWith("&") ? 1
: trailingStringIfTextCut.Length;
maxCharacters = maxCharacters - trailLength >= 0 ? maxCharacters - trailLength
: 0;
int pos = text.LastIndexOf(" ", maxCharacters);
if (pos >= 0)
return text.Substring(0, pos) + trailingStringIfTextCut;
return string.Empty;
}
This is what I use in my projects, with optional trailing. Text will never exceed the maxCharacters + trailing text length.
If you are using windows forms, in the Graphics.DrawString method, there is an option in StringFormat to specify if the string should be truncated, if it does not fit into the area specified. This will handle adding the ellipsis as necessary.
http://msdn.microsoft.com/en-us/library/system.drawing.stringtrimming.aspx
I took your approach a little further:
public string TruncateAtWord(string value, int length)
{
if (value == null || value.Trim().Length <= length)
return value;
int index = value.Trim().LastIndexOf(" ");
while ((index + 3) > length)
index = value.Substring(0, index).Trim().LastIndexOf(" ");
if (index > 0)
return value.Substring(0, index) + "...";
return value.Substring(0, length - 3) + "...";
}
I'm using this to truncate tweets.
This solution works too (takes first 10 words from myString):
String.Join(" ", myString.Split(' ').Take(10))
Taking into account more than just a blank space separator (e.g. words can be separated by periods followed by newlines, followed by tabs, etc.), and several other edge cases, here is an appropriate extension method:
public static string GetMaxWords(this string input, int maxWords, string truncateWith = "...", string additionalSeparators = ",-_:")
{
int words = 1;
bool IsSeparator(char c) => Char.IsSeparator(c) || additionalSeparators.Contains(c);
IEnumerable<char> IterateChars()
{
yield return input[0];
for (int i = 1; i < input.Length; i++)
{
if (IsSeparator(input[i]) && !IsSeparator(input[i - 1]))
if (words == maxWords)
{
foreach (char c in truncateWith)
yield return c;
break;
}
else
words++;
yield return input[i];
}
}
return !input.IsNullOrEmpty()
? new String(IterateChars().ToArray())
: String.Empty;
}
simplified, added trunking character option and made it an extension.
public static string TruncateAtWord(this string value, int maxLength)
{
if (value == null || value.Trim().Length <= maxLength)
return value;
string ellipse = "...";
char[] truncateChars = new char[] { ' ', ',' };
int index = value.Trim().LastIndexOfAny(truncateChars);
while ((index + ellipse.Length) > maxLength)
index = value.Substring(0, index).Trim().LastIndexOfAny(truncateChars);
if (index > 0)
return value.Substring(0, index) + ellipse;
return value.Substring(0, maxLength - ellipse.Length) + ellipse;
}
Heres what i came up with. This is to get the rest of the sentence also in chunks.
public static List<string> SplitTheSentenceAtWord(this string originalString, int length)
{
try
{
List<string> truncatedStrings = new List<string>();
if (originalString == null || originalString.Trim().Length <= length)
{
truncatedStrings.Add(originalString);
return truncatedStrings;
}
int index = originalString.Trim().LastIndexOf(" ");
while ((index + 3) > length)
index = originalString.Substring(0, index).Trim().LastIndexOf(" ");
if (index > 0)
{
string retValue = originalString.Substring(0, index) + "...";
truncatedStrings.Add(retValue);
string shortWord2 = originalString;
if (retValue.EndsWith("..."))
{
shortWord2 = retValue.Replace("...", "");
}
shortWord2 = originalString.Substring(shortWord2.Length);
if (shortWord2.Length > length) //truncate it further
{
List<string> retValues = SplitTheSentenceAtWord(shortWord2.TrimStart(), length);
truncatedStrings.AddRange(retValues);
}
else
{
truncatedStrings.Add(shortWord2.TrimStart());
}
return truncatedStrings;
}
var retVal_Last = originalString.Substring(0, length - 3);
truncatedStrings.Add(retVal_Last + "...");
if (originalString.Length > length)//truncate it further
{
string shortWord3 = originalString;
if (originalString.EndsWith("..."))
{
shortWord3 = originalString.Replace("...", "");
}
shortWord3 = originalString.Substring(retVal_Last.Length);
List<string> retValues = SplitTheSentenceAtWord(shortWord3.TrimStart(), length);
truncatedStrings.AddRange(retValues);
}
else
{
truncatedStrings.Add(retVal_Last + "...");
}
return truncatedStrings;
}
catch
{
return new List<string> { originalString };
}
}
I use this
public string Truncate(string content, int length)
{
try
{
return content.Substring(0,content.IndexOf(" ",length)) + "...";
}
catch
{
return content;
}
}