Very interested in the implementation of Array.Reverse [duplicate] - c#

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Logic behind the Array.Reverse method
I can not find an source of this method. Who knows how it is implemented?
char[] inputstream = source.ToCharArray();
Array.Reverse(inputstream);

Using .NET Reflector :)
public static void Reverse(Array array, int index, int length)
{
if (array == null)
{
throw new ArgumentNullException("array");
}
if ((index < array.GetLowerBound(0)) || (length < 0))
{
throw new ArgumentOutOfRangeException((index < 0) ? "index" : "length", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if ((array.Length - (index - array.GetLowerBound(0))) < length)
{
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
}
if (array.Rank != 1)
{
throw new RankException(Environment.GetResourceString("Rank_MultiDimNotSupported"));
}
if (!TrySZReverse(array, index, length))
{
int num = index;
int num2 = (index + length) - 1;
object[] objArray = array as object[];
if (objArray == null)
{
while (num < num2)
{
object obj3 = array.GetValue(num);
array.SetValue(array.GetValue(num2), num);
array.SetValue(obj3, num2);
num++;
num2--;
}
}
else
{
while (num < num2)
{
object obj2 = objArray[num];
objArray[num] = objArray[num2];
objArray[num2] = obj2;
num++;
num2--;
}
}
}
}

Related

Algorithm for the implementation of merge sort using link array(pointers)

int a[SIZE];
int link[SIZE];
int MergeLists(int i, int j)
{
int head;
int *pprev = &head;
while((i != -1) && (j != -1)){
if(a[i] <= a[j]){
*pprev = i;
pprev = &link[i];
i=*pprev;
} else {
*pprev = j;
pprev = &link[j];
j=*pprev;
}
}
if(i == -1)
*pprev=j;
else
*pprev=i;
printf("%d head",head);
return head;
}
int MergeSort(int low, int end)
{
int mid, i, j;
if((end - low) == 0){
return low;
}
if((end - low) == 1){
link[low] = -1;
return low;
}
if((end - low) == 2){
if(a[low] <= a[end-1]){
link[low] = end-1;
link[end-1] = -1;
return low;
} else {
link[end-1] = low;
link[low] = -1;
return end-1;
}
}
mid = (low+end)/2;
i = MergeSort(low, mid);
j = MergeSort(mid, end);
return MergeLists(i, j);
}
int main()
{
int i;
for(i=0;i<SIZE;++i)
{
printf("\nenter element number %d: ",i+1);
scanf("%d",&a[i]);
}
i = MergeSort(1, SIZE);
do{
printf("%3d", a[i]);
i = link[i];
}while(i != -1);
return 0;
}
to implement merge sort using link array(pinters)
error is given below
input 4 5 2 1
output 1 2 5
MergeLists() uses head for the start of a list (the old code uses link[0]), and -1 for the end of a list (the old code uses 0). This allows sorting of a[0] to a[n-1] (the old code was sorting a[1] to a[n], with a[0] unused).
Well, it seems to be a minor problem, just change the function call in main to
i = MergeSort(0, SIZE);
In C or C++, the index starts with 0, and it is also true when we try to write a function.

Invalid expression term '&&' [duplicate]

This question already has an answer here:
Invalid expression term
(1 answer)
Closed 4 years ago.
I copy the code straight out of the text book and it doesn't work.
Here's the code:
public void BinarySearch(int[] numlist, int value)
{
int min = 0;
int max = numlist.Length - 1;
int index = -1;
while (min <= && index == -1)
{
int mid = (min + max) / 2;
if (value > numlist[mid])
{
min = mid + 1;
}
else if ( value< numlist[mid])
{
max = mid - 1;
}
else
{
index = mid;
}
}
return index;
}
The error I get is:
"Invalid expression term '&&'"
What have I done wrong? I have battled this before and not found an answer for it on StackOverflow.
You want to compare min with max not && and that condition have two part
then the code would be (from what I am seeing BainarySearch):
public void BinarySearch(int[] numlist, int value)
{
int min = 0;
int max = numlist.Length - 1;
int index = -1;
while (min <=max && index == -1)
{
int mid = (min + max) / 2;
if (value > numlist[mid])
{
min = mid + 1;
}
else if ( value< numlist[mid])
{
max = mid - 1;
}
else
{
index = mid;
}
}
return index;
}
You are missing a value in your while condition:
while (min <= [here goes your value] && index == -1)
problem is min <= ? what
while (min <= && index == -1)

Largest substring composed of identical characters

I want to develop method that will return the length of largest substring composed of identical characters form string that is passed as argument, but without using any of .NET libraries.
For example if we pass aaacccccdefffgg as parameter the biggest substring is ccccc and method should return 5.
Here is my working solution :
public static int GetMaxSubstringLenght(char[] myArray)
{
int max = 0;
for (int i = 0; i < myArray.Length-1; i++)
{
if (myArray.Length == 0)
{
return 0;
}
else
{
int j = i + 1;
int currentMax = 1; // string has some value, so we start with 1
while (myArray[i] == myArray[j])
{
currentMax++;
if (max < currentMax)
{
max = currentMax;
}
j++;
}
}
}
return max;
}
The code above will return expected result, but there will be some unnecessary iteration in for loop that I want to avoid. In first iteration when i=0it will compare it until j=2 and then will get out of while loop and start second iteration in for loop comparing the one at [1] index with [2], which we already did in previous iteration.So basically, when first iteration is completed, next one should start from the last value of j. How can I achieve that ?
Thank You in advance.
Since you want "Largest substring..." let's take String as argument and return String
public static String GetMaxSubstring(String value) {
if (String.IsNullOrEmpty(value))
return "";
int bestCount = 0;
char bestChar = '\0';
int currentCount = 0;
char current = '\0';
for (int i = 0; i < value.Length; ++i) {
if ((i == 0) || (value[i] != current))
currentCount = 0;
currentCount += 1;
current = value[i];
if (currentCount > bestCount) {
bestCount = currentCount;
bestChar = current;
}
}
return new String(bestChar, bestCount);
}
....
// "ccccc"
String result = GetMaxSubstring("aaacccccdefffgg");
// 5
int length = result.Length;
Another approach:
public static int MaxSubstringLength(string s)
{
if (string.IsNullOrEmpty(s))
return 0;
int max = 0, cur = 1;
for (int i = 1; i < s.Length; ++i, ++cur)
{
if (s[i] != s[i-1])
{
max = cur > max ? cur : max;
cur = 0;
}
}
return cur > max ? cur : max;
}
[EDIT] Simplified the code.
[EDIT2] Simplified the code further.
you also can do it with one loop:
public static int GetMaxSubstringLenght(char[] myArray)
{
int max = 0;
char currentchar = myArray[0];
int count = 1;
for each(char c in myArray)
{
if(currentchar != c)
{
count = 1;
currentchar = c;
}
if(count > max)
{
max = count;
}
count++;
}
return max;
}
I changed the code... now this code does not use math.max and I think I eleminated the mistake... I've no IDE at the moment to test it
public static int GetMaxSubstringLenght(char[] myArray)
{
if (myArray.Length == 0)
return 0;
if (myArray.Length == 1)
return 1;
int max = 1;
int localMax = 1;
for (int i = 0; i < myArray.Length - max; i++ )
{
if (myArray[i] == myArray[i + 1])
{
localMax++;
}
else
{
max = Math.Max(max, localMax);
localMax = 1;
}
}
return Math.Max(max, localMax);
}
static int LongestCharSequence(string s)
{
if (string.IsNullOrEmpty(s)) return 0;
var prevChar = '\0';
int cmax = 0;
int max = 1;
foreach (char c in s)
{
if (c != prevChar)
{
cmax = 1;
prevChar = c;
}
else
{
if (++cmax > max) max = cmax;
}
}
return max;
}
recursion!
static int LongestCharSequence(string s)
{
int i = (s?.Length ?? 0) == 0 ? 0 : 1;
for (; i < s?.Length; i++)
if (s[i] != s[i - 1]) return Math.Max(i, LongestCharSequence(s.Substring(i)));
return i;
}
Another solution using my favorite nested loop technique:
public static int MaxSubstringLength(string s)
{
int maxLength = 0;
for (int length = s != null ? s.Length : 0, pos = 0; pos < length;)
{
int start = pos;
while (++pos < length && s[pos] == s[start]) { }
maxLength = Math.Max(maxLength, pos - start);
}
return maxLength;
}

Unicode to Mazovia Encoding redundant char

I've been dealing with this for a few hours. I'm saving a string containing Polish diacritics ąśółńźć etc. to a file, but the software I must use to read that file reads only in Mazovia encoding, a pretty old encoding and not supported by the Microsoft Encoding class.
A .Net string consists of UTF-16 characters, so I've been using this code to convert from Unicode to Mazovia.
string rekord = (linia.Substring(0, linia.Length - 1)) + Environment.NewLine;
string rekordMazovia = Kodowanie.UnicodeNaMazovia(rekord);
File.AppendAllText(sciezka, rekordMazovia);
public static class Kodowanie {
public static string UnicodeNaMazovia(string tekst) {
return tekst
.Replace((char)0x104, (char)0x8F) //Ą
.Replace((char)0x106, (char)0x95) //Ć
.Replace((char)0x118, (char)0x90) //Ę
.Replace((char)0x141, (char)0x9C) //Ł
.Replace((char)0x143, (char)0xA5) //Ń
.Replace((char)0xD3, (char)0xA3) //Ó
.Replace((char)0x15A, (char)0x98) //Ś
.Replace((char)0x179, (char)0xA0) //Ź
.Replace((char)0x17B, (char)0xA1) //Ż
.Replace((char)0x105, (char)0x86) //ą
.Replace((char)0x107, (char)0x8D) //ć
.Replace((char)0x119, (char)0x91) //ę
.Replace((char)0x142, (char)0x92) //ł
.Replace((char)0x144, (char)0xA4) //ń
.Replace((char)0xF3, (char)0xA2) //ó
.Replace((char)0x15B, (char)0x9E) //ś
.Replace((char)0x17A, (char)0xA6) //ź
.Replace((char)0x17C, (char)0xA7); //ż
}
}
Everything would be fine except after reading the generated file in the application I get one redundant char > before every diacritic. It looks like this
How to get rid of it? How to do it better?
Mazovia encoding is like code page 437 but it has different letters at some positions so you can't use 437.
If you implement MazoviaEncoding, you can easily use
Encoding encoding = new MazoviaEncoding();
String output = "ąśółńźć";
File.WriteAllText(#"test.txt", output, encoding);
//File.AppendAllText(#"test.txt", output, encoding);
// will work just as well, just pass the encoding as 3rd parameter
The file will contain:
0x86 0x9E 0xA2 0x92 0xA4 0xA6 0x8D
Which is correct according to http://en.wikipedia.org/wiki/Mazovia_encoding
The implementation can then be used like other Encoding in C#. For instance, reading the file back works as well:
Encoding encoding = new MazoviaEncoding();
String result = File.ReadAllText(#"test.txt", encoding);
Here's my implementation:
using System.Collections.Generic;
using System.Text;
namespace System.Text {
class MazoviaEncoding : Encoding
{
private static int[] codePoints = {
0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000A,0x000B,0x000C,0x000D,0x000E,0x000F
,0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001A,0x001B,0x001C,0x001D,0x001E,0x001F
,0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F
,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F
,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F
,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F
,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F
,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F
,0x00C7,0x00FC,0x00E9,0x00E2,0x00E4,0x00E0,0x0105,0x00E7,0x00EA,0x00EB,0x00E8,0x00EF,0x00EE,0x0107,0x00C4,0x0104
,0x0118,0x0119,0x0142,0x00F4,0x00F6,0x0106,0x00FB,0x00F9,0x015A,0x00D6,0x00DC,0x00A2,0x0141,0x00A5,0x015B,0x0192
,0x0179,0x017B,0x00F3,0x00D3,0x0144,0x0143,0x017A,0x017C,0x00BF,0x2310,0x00AC,0x00BD,0x00BC,0x00A1,0x00AB,0x00BB
,0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255D,0x255C,0x255B,0x2510
,0x2514,0x2534,0x252C,0x251C,0x2500,0x253C,0x255E,0x255F,0x255A,0x2554,0x2569,0x2566,0x2560,0x2550,0x256C,0x2567
,0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256B,0x256A,0x2518,0x250C,0x2588,0x2584,0x258C,0x2590,0x2580
,0x03B1,0x00DF,0x0393,0x03C0,0x03A3,0x03C3,0x00B5,0x03C4,0x03A6,0x0398,0x03A9,0x03B4,0x221E,0x03C6,0x03B5,0x2229
,0x2261,0x00B1,0x2265,0x2264,0x2320,0x2321,0x00F7,0x2248,0x00B0,0x2219,0x00B7,0x221A,0x207F,0x00B2,0x25A0,0x00A0
};
private static Dictionary<char, byte> unicodeToByte;
static MazoviaEncoding()
{
unicodeToByte = new Dictionary<char, byte>();
for (int i = 0; i < codePoints.Length; ++i)
{
unicodeToByte.Add((char)codePoints[i], (byte)i);
}
}
public override int GetMaxByteCount(int charCount)
{
if (charCount < 0)
{
throw new ArgumentOutOfRangeException();
}
return charCount;
}
public override int GetMaxCharCount(int byteCount)
{
if (byteCount < 0)
{
throw new ArgumentOutOfRangeException();
}
return byteCount;
}
public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
{
if( chars == null || bytes == null ) {
throw new ArgumentNullException();
}
if( charIndex + charCount > chars.Length ||
charIndex < 0 ||
byteIndex < 0 ||
byteIndex + charCount > bytes.Length
) {
throw new ArgumentOutOfRangeException();
}
int total = 0;
int j = 0;
for (int i = charIndex; i < charIndex + charCount; ++i)
{
char cur = chars[i];
byte asMazovia;
if (!unicodeToByte.TryGetValue(cur, out asMazovia))
{
asMazovia = (byte)0x003F; // "?"
}
total++;
bytes[j+byteIndex] = asMazovia;
j++;
}
return total;
}
public override int GetChars( byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex )
{
if (chars == null || bytes == null)
{
throw new ArgumentNullException();
}
if ( byteIndex + byteCount > bytes.Length ||
charIndex < 0 ||
byteIndex < 0 ||
charIndex + byteCount > chars.Length
)
{
throw new ArgumentOutOfRangeException();
}
int total = 0;
int j = 0;
for (int i = byteIndex; i < byteIndex + byteCount; ++i)
{
byte cur = bytes[i];
char decoded = (char)codePoints[cur];
total++;
chars[charIndex + j] = decoded;
j++;
}
return total;
}
public override int GetByteCount(char[] charArray, int index, int count)
{
if (charArray == null)
{
throw new ArgumentNullException();
}
if (index + count <= charArray.Length && index >= 0 && count >= 0)
{
return count;
}
else
{
throw new ArgumentOutOfRangeException();
}
}
public override int GetCharCount( byte[] bytes, int index, int count )
{
if (bytes == null)
{
throw new ArgumentNullException();
}
if (index < 0 || count < 0 || index + count > bytes.Length)
{
throw new ArgumentOutOfRangeException();
}
return count;
}
}
}

n-th prime number problem, need to speed it up a bit

There is simple cipher that translates number to series of . ( )
In order to encrypt a number (0 .. 2147483647) to this representation, I (think I) need:
prime factorization
for given p (p is Prime), order sequence of p (ie. PrimeOrd(2) == 0, PrimeOrd(227) == 49)
Some examples
0 . 6 (()())
1 () 7 (...())
2 (()) 8 ((.()))
3 (.()) 9 (.(()))
4 ((())) 10 (().())
5 (..()) 11 (....())
227 (................................................())
2147483648 ((..........()))
My source code for the problem
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
static class P
{
static List<int> _list = new List<int>();
public static int Nth(int n)
{
if (_list.Count == 0 || _list.Count < n)
Primes().Take(n + 1);
return _list[n];
}
public static int PrimeOrd(int prime)
{
if (_list.Count == 0 || _list.Last() < prime)
Primes().First(p => p >= prime);
return (_list.Contains(prime)) ? _list.FindIndex(p => p == prime) : -1;
}
public static List<int> Factor(int N)
{
List<int> ret = new List<int>();
for (int i = 2; i ≤ N; i++)
while (N % i == 0)
{
N /= i;
ret.Add(i);
}
return ret;
}
public static IEnumerable<int> Primes()
{
_list = new List<int>();
_list.Add(2);
yield return 2;
Func<int, bool> IsPrime = n => _list.TakeWhile(p => p ≤ (int)Math.Sqrt(n)).FirstOrDefault(p => n % p == 0) == 0;
for (int i = 3; i < Int32.MaxValue; i += 2)
{
if (IsPrime(i))
{
_list.Add(i);
yield return i;
}
}
}
public static string Convert(int n)
{
if (n == 0) return ".";
if (n == 1) return "()";
StringBuilder sb = new StringBuilder();
var p = Factor(n);
var max = PrimeOrd(p.Last());
for (int i = 0; i ≤ max; i++)
{
var power = p.FindAll((x) => x == Nth(i)).Count;
sb.Append(Convert(power));
}
return "(" + sb.ToString() + ")";
}
}
class Program
{
static void Main(string[] args)
{
string line = Console.ReadLine();
try
{
int num = int.Parse(line);
Console.WriteLine("{0}: '{1}'", num, P.Convert(num));
}
catch
{
Console.WriteLine("You didn't entered number!");
}
}
}
The problem is SLOWNESS of procedure PrimeOrd. Do you know some FASTER solution for finding out order of prime in primes?
Heading
If You know how to speed-up finding order of prime number, please, suggest something. :-)
Thank You.
P.S. The biggest prime less than 2,147,483,648 is 2,147,483,647 and it's 105,097,565th prime. There is no need to expect bigger number than 2^31.
This is not something you should be doing at run-time. A better option is to pre-calculate all these primes and then put them in your program somehow (a static array, or a file to be read in). The slow code is then run as part of the development process (which is slow anyway :-), not at the point where you need your speed.
Then it's just a matter of a lookup of some sort rather than calculating them every time you need them.
Please see SO questions:
http://www.google.com/search?q=site%3Astackoverflow.com+prime+number&btnG=Search
Finding prime numbers with the Sieve of Eratosthenes (Originally: Is there a better way to prepare this array?)
Prime number calculation fun
How can I find prime numbers through bit operations in C++?
prime numbers c#
Finding composite numbers
Prime numbers program
If you need a list of known primes, have a look here
You should cache the primes to _list and then use it for both Factor and PrimeOrd. Additionally avoid operators LINQ operators like TakeWhile that create values that you throw away.
Here's an optimized version:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
static class P
{
private static List<int> _list = new List<int>();
public static int Nth(int n)
{
if (_list.Count == 0 || _list.Count <= n)
{
GenerateNextPrimes().First(p => _list.Count >= n);
}
return _list[n];
}
public static int PrimeOrd(int prime)
{
var primes = GrowPrimesTo(prime);
return primes.IndexOf(prime);
}
public static List<int> Factor(int N)
{
List<int> ret = new List<int>();
GrowPrimesTo(N);
for (int ixDivisor = 0; ixDivisor < _list.Count; ixDivisor++)
{
int currentDivisor = _list[ixDivisor];
while (N % currentDivisor == 0)
{
N /= currentDivisor;
ret.Add(currentDivisor);
}
if (N <= 1)
{
break;
}
}
return ret;
}
private static List<int> GrowPrimesTo(int max)
{
if (_list.LastOrDefault() >= max)
{
return _list;
}
GenerateNextPrimes().First(prime => prime >= max);
return _list;
}
private static IEnumerable<int> GenerateNextPrimes()
{
if (_list.Count == 0)
{
_list.Add(2);
yield return 2;
}
Func<int, bool> IsPrime =
n =>
{
// cache upperBound
int upperBound = (int)Math.Sqrt(n);
for (int ixPrime = 0; ixPrime < _list.Count; ixPrime++)
{
int currentDivisor = _list[ixPrime];
if (currentDivisor > upperBound)
{
return true;
}
if ((n % currentDivisor) == 0)
{
return false;
}
}
return true;
};
// Always start on next odd number
int startNum = _list.Count == 1 ? 3 : _list[_list.Count - 1] + 2;
for (int i = startNum; i < Int32.MaxValue; i += 2)
{
if (IsPrime(i))
{
_list.Add(i);
yield return i;
}
}
}
public static string Convert(int n)
{
if (n == 0) return ".";
if (n == 1) return "()";
StringBuilder sb = new StringBuilder();
var p = Factor(n);
var max = PrimeOrd(p.Last());
for (int i = 0; i <= max; i++)
{
var power = p.FindAll(x => x == Nth(i)).Count;
sb.Append(Convert(power));
}
return "(" + sb.ToString() + ")";
}
}
class Program
{
static void Main(string[] args)
{
string line = Console.ReadLine();
int num;
if(int.TryParse(line, out num))
{
Console.WriteLine("{0}: '{1}'", num, P.Convert(num));
}
else
{
Console.WriteLine("You didn't entered number!");
}
}
}

Categories

Resources