I have method for converting array of Booleans to integer. It looks like this
class Program
{
public static int GivMeInt(bool[] outputs)
{
int data = 0;
for (int i = 0; i < 8; i++)
{
data += ((outputs[i] == true) ? Convert.ToInt32(Math.Pow(2, i)) : 0);
}
return data;
}
static void Main(string[] args)
{
bool[] outputs = new bool[8];
outputs[0] = false;
outputs[1] = true;
outputs[2] = false;
outputs[3] = true;
outputs[4] = false;
outputs[5] = false;
outputs[6] = false;
outputs[7] = false;
int data = GivMeInt(outputs);
Console.WriteLine(data);
Console.ReadKey();
}
}
Now I want to make opposite method returning array of Booleans values
As I am short with knowledge of .NET and C# until now I have only my mind hardcoding of switch statement or if conditions for every possible int value.
public static bool[] GiveMeBool(int data)
{
bool[] outputs = new bool[8];
if (data == 0)
{
outputs[0] = false;
outputs[1] = false;
outputs[2] = false;
outputs[3] = false;
outputs[4] = false;
outputs[5] = false;
outputs[6] = false;
outputs[7] = false;
}
//After thousand lines of coed
if (data == 255)
{
outputs[0] = true;
outputs[1] = true;
outputs[2] = true;
outputs[3] = true;
outputs[4] = true;
outputs[5] = true;
outputs[6] = true;
outputs[7] = true;
}
return outputs;
}
I know that there must be easier way.
You need to use bitwise operators: (Tested)
public static bool[] GiveMeBool(int data) {
bool[] outputs = new bool[8];
for(int i = 0; i < 8; i++)
outputs[i] = (data & (1 << i)) == (1 << i);
return outputs;
}
You can also use bitwise operators to make your original much faster: (Untested)
public static int GivMeInt(bool[] outputs) {
int data = 0;
for (int i = 0; i < 8; i++)
data += outputs[i] ? 1 << i : 0;
return data;
}
This uses bit shifting.
public static bool[] GiveMeBool(Int32 data)
{
bool[] bits = new bool[32];
for (i = 0; i <= bits.Length - 1; i++) {
bits(i) = (data & 1) == 1;
data >>= 1;
}
return bits;
}
This whole thing can be changed to use bitmaps using shift operators.
Try this...
public static bool[] GiveMeBool(int data)
{
bool[] outputs = new bool[8];
for (int i = 0; i < 8; i++)
outputs[i] = (data & (int)Math.Pow(2, i)) != 0;
return outputs;
}
What about something like the following?
Int32 x = 0xFF33;
bool[] retval = new bool[32];
for (int i = 0; i < 32 && x != 0; i++, x = x >> 1)
{
retval[i] = (x & 1) == 1;
}
It uses bit-shifting to do its magic.
I tested the methods in Java. The only significant difference is the bool vs boolean keywords.
public class Test {
public static void main(String[] args) {
boolean[] bools = new boolean[]{true,true,false,false,false,false,false,false};
int num = GivMeInt(bools);
boolean[] bools2 = GivMeBools(num);
for(int i = 0; i < 8; i++) System.out.println(bools[i]==bools2[i]);
}
public static int GivMeInt(boolean[] outputs)
{
int data = 0;
for (int i = 0; i < 8; i++)
{
if(outputs[i]) {
data += (1 << i);
}
}
return data;
}
public static boolean[] GivMeBools(int input)
{
boolean[] outputs = new boolean[8];
for (int i = 0; i < 8; i++)
{
outputs[i] = (input & 0x1) == 1;
input = input >>> 1;
}
return outputs;
}
}
Related
G'Day. I am attempting to convert a function that was initially made for Bohemia Interactives language SQF to C#. The script is designed to encrypt a string with the encryption method RC4, however, it works a little bit different to the way this is traditionally done thanks to limitations of the arma3 engine. The whole idea of this is so I can encrypt a string with the C# program, and decrypt it through Arma 3 in-game.
Here is the code I am trying to convert from.
/*
Function: ALiVE_fnc_crypt
Author(s): Naught
Version: 1.0
Description:
Encrypts or decrypts a string with a specified encryption key.
Parameters:
0 - Decrypt (0) or encrypt (1) [number]
1 - Encryption method name [string]
2 - Encrypted or plain data [string]
3 - Encryption key [string]
Returns:
Encrypted or decrypted data or nothing on failure [string:nil]
Note(s):
1. Current encryption method names:
- "rc4" // Rivest Cipher 4 Stream Encryption Algorithm
*/
// Constants
MAX_CHAR_SIZE = 8;
CHAR_ZERO_REP = 256;
private ["_method", "_key"];
_encText = _this select 0;
_key = _this select 1;
private ["_fnc_intToBin"];
_fnc_intToBin = {
private ["_int", "_bin", "_pwr", "_bool"];
_int = _this select 0;
_bin = if ((count _this) > 1) then {_this select 1} else {[]};
for "_i" from (MAX_CHAR_SIZE - 1) to 0 step (-1) do
{
_pwr = 2^(_i);
_bool = _pwr <= _int;
_bin set [(count _bin), _bool];
if (_bool) then {_int = _int - _pwr};
};
_bin
};
private ["_bin"];
_bin = [];
// Convert string to UTF-8 binary
{ // count (faster than forEach)
[(if (_x == CHAR_ZERO_REP) then {0} else {_x}), _bin] call _fnc_intToBin;
false;
} count toArray(_encText);
systemChat str _bin;
// Encrypt & decrypt methods
_key = toArray(_key);
private ["_keyLen", "_state", "_temp", "_j"];
_keyLen = count _key;
_state = [];
_temp = 0;
_j = 0;
// Key-Scheduling Algorithm
for "_i" from 0 to 255 do {_state set [_i,_i]};
for "_i" from 0 to 255 do
{
_temp = _state select _i;
_j = (_j + _temp + (_key select (_i mod _keyLen))) mod 256;
_state set [_i, (_state select _j)];
_state set [_j, _temp];
};
private ["_temp1", "_temp2", "_rand", "_i", "_mod", "_rbit"];
_temp1 = 0;
_temp2 = 0;
_rand = [];
_i = 0;
_j = 0;
hint str _bin;
// Pseudo-Random Generation Algorithm
{
_mod = _forEachIndex % MAX_CHAR_SIZE;
if (_mod == 0) then
{
_i = (_i + 1) mod 256;
_j = (_j + (_state select _i)) mod 256;
_temp1 = _state select _i;
_temp2 = _state select _j;
_state set [_i, _temp2];
_state set [_j, _temp1];
_rand = [(_state select ((_temp1 + _temp2) mod 256))] call _fnc_intToBin;
};
_rbit = _rand select _mod;
_bin set [_forEachIndex, (_x && !_rbit) || {!_x && _rbit}]; // XOR
} forEach _bin;
private ["_dec", "_buf", "_mod"];
_dec = 0;
_buf = [];
// Convert binary array to UTF-8 string
{
_mod = _forEachIndex % MAX_CHAR_SIZE;
if (_x) then {_dec = _dec + 2^((MAX_CHAR_SIZE - 1) - _mod)};
if (_mod == 7) then
{
if (_dec == 0) then {_dec = CHAR_ZERO_REP};
_buf set [(count _buf), _dec];
_dec = 0;
};
} forEach _bin;
toString(_buf)
I have made slight adjustments to this code, and it all still works fine in Arma 3.
Now, the converted function. I have changed about everything in this code from what my initial code was to try and get it working, so at this point, it may be completely incorrect, however, I will include it anyway.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace encrypt
{
class Program
{
static public int MAX_CHAR_SIZE = 8;
static public int CHAR_ZERO_REP = 256;
static public int _keyLen;
static void Main()
{
string[] args = new string[2];
args[0] = "Some Random Code";
args[1] = "4tuIc9tai";
string text = args[0];
// Convert the text to an array of decimal unicode || Same as toArray in arma 3
string[] txtArray = new string[text.Length];
txtArray = text.ToCharArray().Select(c => c.ToString()).ToArray();
int[] utf = getUni(txtArray);
// Convert the key to an array of decimal unicode || Same as toArray in arma 3
string[] keyArray = new string[args[1].Length];
keyArray = args[1].ToCharArray().Select(c => c.ToString()).ToArray();
int[] key = getUni(keyArray);
// Debug the output
//foreach (int i in utf){Console.Write(i); Console.Write(",");} Console.WriteLine();foreach (int i in key){Console.Write(i);Console.Write(","); }
// Convert string to UTF-8 binary
Dictionary<int, bool> _bin = new Dictionary<int, bool>();
foreach (int i in utf)
{
int _num;
if (i == CHAR_ZERO_REP)
{
_num = 0;
}
else
{
_num = i;
}
_bin = intToBin(_num, _bin);
}
foreach (KeyValuePair<int, bool> i in _bin)
{
Console.Write(Convert.ToString(i.Value));
Console.Write(", ");
}
// Encrypt & decrypt methods
_keyLen = key.Length;
int[] _state = new int[1024];
int _temp = 0;
int _j = 0;
// Key-Scheduling Algorithm
for (int _i = 0; _i < 255; _i++)
{
_state.SetValue(_i, _i);
}
for (int _i = 0; _i < 255; _i++)
{
_temp = _state[_i];
_j = (_j + _temp + key[_i % _keyLen]) % 256;
_state.SetValue(_i, _state[_j]);
_state.SetValue(_j, _temp);
}
// Pseudo-Random Generation Algorithm
int _temp1 = 0;
int _temp2 = 0;
Dictionary<int, bool> _rand = new Dictionary<int, bool>();
int __i = 0;
int __j = 0;
int indx = 0;
for (int i = 0; i < _bin.Count-1; i++)
{
int _mod = indx % MAX_CHAR_SIZE;
if (_mod == 0)
{
__i = (__i + 1) % 256;
__j = (__j + _state[__i]) % 256;
_temp1 = _state[__i];
_temp2 = _state[__j];
_state.SetValue(__i, _temp2);
_state.SetValue(__j, _temp1);
_rand = intToBin(_state[_temp1 + _temp2] % 256, _rand);
}
bool _rbit = _rand[_mod];
bool _bit = _bin[i];
if (_bin.ContainsKey(indx))
{
_bin.Remove(indx);
}
_bin.Add(indx, (_bit && !_rbit) || (!_bit && _rbit));
indx++;
}
// Convert binary array to UTF-8 string
int _dec = 0;
int[] _buf = new int[_bin.Count];
for (int i = 0; i < _bin.Count-1; i++)
{
int _mod = i % MAX_CHAR_SIZE;
Console.WriteLine(i);
if (_bin[i])
{
_dec = _dec + 2 ^ ((MAX_CHAR_SIZE - 1) - _mod);
}
if (_mod == 7)
{
if (_dec == 0)
{
_dec = CHAR_ZERO_REP;
}
_buf.SetValue(_dec, _buf.Length-1);
_dec = 0;
}
_buf.SetValue(_dec, _buf.Length - 1);
}
Console.ReadLine();
}
static int[] getUni(string[] txtArray)
{
int[] ret = new int[txtArray.Length];
int idx = 0;
foreach (string i in txtArray)
{
ret.SetValue(Encoding.UTF8.GetBytes(i)[0], idx);
idx++;
}
return ret;
}
static Dictionary<int, bool> intToBin(int val, Dictionary<int, bool> bin)
{
for (int i = MAX_CHAR_SIZE-1; i > 0; i--)
{
int _pwr = 2 ^ i;
bool _bool = _pwr <= val;
int cc = bin.Count;
if (bin.ContainsKey(cc))
{
bin.Remove(cc);
}
bin.Add(cc, _bool);
if (_bool)
{
val = val - _pwr;
}
}
return bin;
}
}
}
Any help what so ever would be great :)
I am trying to solve this question:
Write a function that finds the zero-based index of the longest run in a string. A run is a consecutive sequence of the same character. If there is more than one run with the same length, return the index of the first one.
For example, IndexOfLongestRun("abbcccddddcccbba") should return 6 as the longest run is dddd and it first appears on index 6.
Following what i have done:
private static int IndexOfLongestRun(string str)
{
char[] array1 = str.ToCharArray();
//Array.Sort(array1);
Comparer comparer = new Comparer();
int counter =1;
int maxCount = 0;
int idenxOf = 0;
for (int i =0; i<array1.Length-1 ; i++)
{
if (comparer.Compare(array1[i],array1[i+1]) == 0)
{
counter++;
}
else {
if(maxCount < counter)
{
maxCount = counter;
idenxOf = i - counter + 1;
}
counter = 1;
}
}
return idenxOf ;
}
}
public class Comparer : IComparer<char>
{
public int Compare(char firstChar, char nextChar)
{
return firstChar.CompareTo(nextChar);
}
}
The problem is that when i get to the last index for example "abbccaaaaaaaaaa"
which is a in this case, and when i=14 (taking this string as example) and when i<array1.Length-1 statment is false, the for loop jumps directrly to return indexOf; and return the wrong index, I am trying to find out how to push the forloop to continue the implementation so idenxOf could be changed to the right index. Any help please?
You could check whether a new best score is achieved for each iteration when current == previous. Minimally slower, but it allows you to write shorter code by omitting an extra check after the loop:
int IndexOfLongestRun(string input)
{
int bestIndex = 0, bestScore = 0, currIndex = 0;
for (var i = 0; i < input.Length; ++i)
{
if (input[i] == input[currIndex])
{
if (bestScore < i - currIndex)
{
bestIndex = currIndex;
bestScore = i - currIndex;
}
}
else
{
currIndex = i;
}
}
return bestIndex;
}
Promote the loop variable i to method scope and repeat the conditional block if (maxCount < counter) { ... } right after the loop exit. Thus, it executes one more time after the loop completes
private static int IndexOfLongestRun(string str)
{
char[] array1 = str.ToCharArray();
//Array.Sort(array1);
Comparer comparer = new Comparer();
int counter = 1;
int maxCount = 0;
int idenxOf = 0;
int i;
for (i = 0; i < array1.Length - 1; i++)
{
if (comparer.Compare(array1[i], array1[i + 1]) == 0)
{
counter++;
}
else
{
if (maxCount < counter)
{
maxCount = counter;
idenxOf = i - counter + 1;
}
counter = 1;
}
}
if (maxCount < counter)
{
maxCount = counter;
idenxOf = i - counter + 1;
}
return idenxOf;
}
As usual late, but joining the party. A natural classic algorithm:
static int IndexOfLongestRun(string input)
{
int longestRunStart = -1, longestRunLength = 0;
for (int i = 0; i < input.Length; )
{
var runValue = input[i];
int runStart = i;
while (++i < input.Length && input[i] == runValue) { }
int runLength = i - runStart;
if (longestRunLength < runLength)
{
longestRunStart = runStart;
longestRunLength = runLength;
}
}
return longestRunStart;
}
At the end you have both longest run index and length.
public static int IndexOfLongestRun(string str)
{
var longestRunCount = 1;
var longestRunIndex = 0;
var isNew = false;
var dic = new Dictionary<int, int>();
for (var i = 0; i < str.Length - 1; i++)
{
if (str[i] == str[i + 1])
{
if (isNew) longestRunIndex = i;
longestRunCount++;
isNew = false;
}
else
{
isNew = true;
dic.Add(longestRunIndex, longestRunCount);
longestRunIndex = 0;
longestRunCount = 1;
}
}
return dic.OrderByDescending(x => x.Value).First().Key;
}
This will return -1 if the string is empty and you have the flexibility of returning the index and the count depending on your specification.
string myStr = "aaaabbbbccccccccccccdeeeeeeeee";
var longestIndexStart = -1;
var longestCount = 0;
var currentCount = 1;
var currentIndexStart = 0;
for (var idx = 1; idx < myStr.Length; idx++)
{
if (myStr[idx] == myStr[currentIndexStart])
currentCount++;
else
{
if (currentCount > longestCount)
{
longestIndexStart = currentIndexStart;
longestCount = currentCount;
}
currentIndexStart = idx;
currentCount = 1;
}
}
return longestIndexStart;
The accepted answer from Kvam works great for small strings, but as the length approaches 100,000 characters (and perhaps this isn't needed), its efficiency wains.
public static int IndexOfLongestRun(string str)
{
Dictionary<string, int> letterCount = new Dictionary<string, int>();
for (int i = 0; i < str.Length; i++)
{
string c = str.Substring(i, 1);
if (letterCount.ContainsKey(c))
letterCount[c]++;
else
letterCount.Add(c, 1);
}
return letterCount.Values.Max();
}
This solution is twice as fast as Kvam's with large strings. There are, perhaps, other optimizations.
here will be my code for famous Knights Tour for 8x8 deck. So, the main idea of my code is: we will choose from Turns our destination, check it with isPossible and then go recursevly to it, marked this cell to '1'. So, check every cell, and if we will be in 64's cell - return true.
But my code goes to infinite recurssion, and I can't debug it, any recommendation will be greatly appreciated.
class Class1
{
static void Main(string[] args)
{
int x = 0;
int y = 0;
Console.WriteLine("Enter X and press enter");
x = Int32.Parse(Console.ReadLine());
Console.WriteLine("Enter Y and press enter");
y = Int32.Parse(Console.ReadLine());
TurnVariation Turns = new TurnVariation();
EmptyBoard Board = new EmptyBoard();
if (TryPut.Put(Board, x, y, Turns, 1, false))
{
Console.WriteLine("МОЖНА!!!!");
}
else
{
Console.WriteLine("NET!!");
}
}
}
public class TryPut : EmptyBoard
{
public static bool Put(EmptyBoard Board, int x, int y, TurnVariation Turns, int count, bool flag)
{
int tempX = 0;
int tempY = 0;
if (count >= 64)
{
Console.WriteLine("yeab");
return true;
}
for (int i = 0; i <= 7; i++)
{
tempX = x + Turns.Turns[i,0];
tempY = y + Turns.Turns[i,1];
//Console.WriteLine(count);
if (IsPossible(Board, tempX, tempY))
{
Board.Array[tempX, tempY] = 1;
flag = Put(Board, tempX, tempY, Turns, count+1, flag);
if (flag)
{
break;
}
Board.Array[tempX, tempY] = 0;
}
}
if (flag)
return true;
else
return false;
}
public static bool IsPossible(EmptyBoard Board, int x, int y)
{
if ((x < 0) || (x > 7) || (y < 0) || (y > 7))
return false;
if (Board.Array[x, y] == 1)
return false;
return true;
}
}
public class TurnVariation
{
public int[,] Turns = new int[8, 2];
public TurnVariation()
{
Turns[0, 0] = -2; Turns[0, 1] = 1;
Turns[1,0] = -2; Turns[1,1] = -1;
Turns[2,0] = -1; Turns[2,1] = 2;
Turns[3,0] = 1; Turns[3,1] = 2;
Turns[4,0] = 2; Turns[4,1] = 1;
Turns[5,0] = 2; Turns[5,1] = -1;
Turns[6,0] = 1; Turns[6,1] = -2;
Turns[7,0] = -1; Turns[7,1] = -2;
}
}
public class EmptyBoard
{
public const int N = 8;
public int[,] Array = new int[N, N];
public EmptyBoard()
{
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
Array[i, j] = 0;
}
}
I think your problem is that your testing for count<64, but you never assign to count. You just pass (by value!) 'Count + 1' to the put method. You are probably thinking that this will bewritten back to the count variable. But that is not the case...
Do note that debugging is the first skill you need to learn!
I have 2 BitArray items and I need to know if any of bits are the same in each, "AND".
However, the length of the BitArrays can be different and ether one can be larger or smaller than the other.
How can I do an "AND" of two BitArrays, without getting an exception because of different sizes?
This is going to happen a lot, so I need it to be fairly quick.
Example
int[] ids = new int[3];
ids[0] = 1;
ids[1] = 3;
ids[2] = 5;
BitArray bs1 = new BitArray(ids.Max()+1);
for (int i = 0; i < ids.Count(); ++i)
{
bs1[ids[i]] = true;
}
ids[0] = 1;
ids[1] = 59;
ids[2] = 1111;
BitArray bs2 = new BitArray(ids.Max()+1);
for (int i = 0; i < ids.Count(); ++i)
{
bs2[ids[i]] = true;
}
ids[0] = 0;
ids[1] = 5;
ids[2] = 33;
BitArray bs3 = new BitArray(ids.Max()+1);
for (int i = 0; i < ids.Count(); ++i)
{
bs3[ids[i]] = true;
}
//if bs1 AND bs2 bitcount > 0 DisplayMessage("1 and 2 has some same items")
//if bs1 AND bs3 bitcount > 0 DisplayMessage("1 and 3 has some same items")
//if bs2 AND bs3 bitcount > 0 DisplayMessage("2 and 3 has some same items")
To solve my problem I modified the BitArray code and added the following
public static MyBitArray TruncateCopy(MyBitArray source, int size)
{
MyBitArray dest = new MyBitArray(size);
//copy all the arrays
for (int i = 0; i < dest.m_array.Length; ++i)
{
dest.m_array[i] = source.m_array[i];
}
//remove any of the items over the given size
for (int i = ((size % 32) + 1); i < 32; ++i)
{
dest.m_array[i >> 5] &= ~(1 << (i & 31));
}
return dest;
}
public bool HasCommonBits(MyBitArray comp)
{
MyBitArray copied, other;
if (this.Length < comp.Length)
{
other = this;
copied = TruncateCopy(comp, this.Length);
}
else
{
copied = TruncateCopy(this, comp.Length);
other = comp;
}
MyBitArray compareEq = copied.And(other);
return (!compareEq.IsEmpty());
}
public bool IsEmpty()
{
for (int i = 0; i < this.m_array.Length; ++i)
{
if (m_array[i] != 0)
return false;
}
return true;
}
public bool IsFull()
{
//run through all the full sets
for (int i = 0; i < this.m_array.Length - 1; ++i)
{
if (m_array[i] != -1) //-1 is all bits set in an integer
return false;
}
//go through the partial one
for (int i = 0; i < (this.Length % 32); ++i)
{
if (!this[i])
return false;
}
return true;
}
}
First, define what you want to happen in case of differing lengths. Maybe you just want to compare the first Math.Min(len1, len2) elements. In that case write a for loop whose index variable ranges from 0 to Math.Min(len1, len2). Compare the respective array elements in the loop body.
I examined BitArray with reflector. There is no way to trim it, or to perform a partial And. You're out of luck with this class. Replace it with a custom-written class that supports what you need. Writing a bit array is not especially hard.
Completely revised based on this comment:
The result bitarray of your example would be 01010. My original problem states that I need to see if any of the bits are the same. Thus the a resulting bitarray with any 1's would be True and all 0's would be False
BitArrray truncateCopyBA(BitArray source, int size)
{
BitArray dest = new BitArray(size);
for(int i = 0; i < size; ++i)
{
dest[i] = source[i];
}
return dest;
}
bool YourFunc(BitArray a, BitArray b)
{
BitArray one, two;
if (a.Length < b.Length)
{
one = a;
two = truncateCopyBA(b, a.Length);
}
else
{
one = truncateCopyBA(a, b.Length);
two = b;
// If you want to see which bits in both arrays are both ones, then use .And()
// If you want to see which bits in both arrays are the same, use .Not(.Xor()).
BitArray compareEq = a.And(b);
bool anyBitsSame=false;
for(int i = 0; i < compareEq.Length; ++i)
{
if(compareEq.Get(i))
{
return true;
}
}
return false
}
}
I believe this is what you're looking for, but honestly your question is still quite vague after clarifications.
This question already has answers here:
Write a function that returns the longest palindrome in a given string
(23 answers)
Closed 9 years ago.
Possible Duplicate:
Write a function that returns the longest palindrome in a given string
I know how to do this in O(n^2). But it seems like there exist a better solution.
I've found this, and there is a link to O(n) answer, but it's written in Haskell and not clear for me.
It would be great to get an answer in c# or similar.
I've found clear explanation of the solution here. Thanks to Justin for this link.
There you can find Python and Java implementations of the algorithm (C++ implementation contains errors).
And here is C# implementation that is just a translation of those algorithms.
public static int LongestPalindrome(string seq)
{
int Longest = 0;
List<int> l = new List<int>();
int i = 0;
int palLen = 0;
int s = 0;
int e = 0;
while (i<seq.Length)
{
if (i > palLen && seq[i-palLen-1] == seq[i])
{
palLen += 2;
i += 1;
continue;
}
l.Add(palLen);
Longest = Math.Max(Longest, palLen);
s = l.Count - 2;
e = s - palLen;
bool found = false;
for (int j = s; j > e; j--)
{
int d = j - e - 1;
if (l[j] == d)
{
palLen = d;
found = true;
break;
}
l.Add(Math.Min(d, l[j]));
}
if (!found)
{
palLen = 1;
i += 1;
}
}
l.Add(palLen);
Longest = Math.Max(Longest, palLen);
return Longest;
}
And this is its java version:
public static int LongestPalindrome(String seq) {
int Longest = 0;
List<Integer> l = new ArrayList<Integer>();
int i = 0;
int palLen = 0;
int s = 0;
int e = 0;
while (i < seq.length()) {
if (i > palLen && seq.charAt(i - palLen - 1) == seq.charAt(i)) {
palLen += 2;
i += 1;
continue;
}
l.add(palLen);
Longest = Math.max(Longest, palLen);
s = l.size() - 2;
e = s - palLen;
boolean found = false;
for (int j = s; j > e; j--) {
int d = j - e - 1;
if (l.get(j) == d) {
palLen = d;
found = true;
break;
}
l.add(Math.min(d, l.get(j)));
}
if (!found) {
palLen = 1;
i += 1;
}
}
l.add(palLen);
Longest = Math.max(Longest, palLen);
return Longest;
}
public static string GetMaxPalindromeString(string testingString)
{
int stringLength = testingString.Length;
int maxPalindromeStringLength = 0;
int maxPalindromeStringStartIndex = 0;
for (int i = 0; i < stringLength; i++)
{
int currentCharIndex = i;
for (int lastCharIndex = stringLength - 1; lastCharIndex > currentCharIndex; lastCharIndex--)
{
if (lastCharIndex - currentCharIndex + 1 < maxPalindromeStringLength)
{
break;
}
bool isPalindrome = true;
if (testingString[currentCharIndex] != testingString[lastCharIndex])
{
continue;
}
else
{
int matchedCharIndexFromEnd = lastCharIndex - 1;
for (int nextCharIndex = currentCharIndex + 1; nextCharIndex < matchedCharIndexFromEnd; nextCharIndex++)
{
if (testingString[nextCharIndex] != testingString[matchedCharIndexFromEnd])
{
isPalindrome = false;
break;
}
matchedCharIndexFromEnd--;
}
}
if (isPalindrome)
{
if (lastCharIndex + 1 - currentCharIndex > maxPalindromeStringLength)
{
maxPalindromeStringStartIndex = currentCharIndex;
maxPalindromeStringLength = lastCharIndex + 1 - currentCharIndex;
}
break;
}
}
}
if(maxPalindromeStringLength>0)
{
return testingString.Substring(maxPalindromeStringStartIndex, maxPalindromeStringLength);
}
return null;
}
C#
First I search for even length palindromes. Then I search for odd length palindromes. When it finds a palindrome, it determines the length and sets the max length accordingly. The average case complexity for this is linear.
protected static int LongestPalindrome(string str)
{
int i = 0;
int j = 1;
int oldJ = 1;
int intMax = 1;
int intCount = 0;
if (str.Length == 0) return 0;
if (str.Length == 1) return 1;
int[] intDistance = new int[2] {0,1};
for( int k = 0; k < intDistance.Length; k++ ){
j = 1 + intDistance[k];
oldJ = j;
intCount = 0;
i = 0;
while (j < str.Length)
{
if (str[i].Equals(str[j]))
{
oldJ = j;
intCount = 2 + intDistance[k];
i--;
j++;
while (i >= 0 && j < str.Length)
{
if (str[i].Equals(str[j]))
{
intCount += 2;
i--;
j++;
continue;
}
else
{
break;
}
}
intMax = getMax(intMax, intCount);
j = oldJ + 1;
i = j - 1 - intDistance[k];
}
else
{
i++;
j++;
}
}
}
return intMax;
}
protected static int getMax(int a, int b)
{
if (a > b) return a; return b;
}
Recently I wrote following code during interview...
public string FindMaxLengthPalindrome(string s)
{
string maxLengthPalindrome = "";
if (s == null) return s;
int len = s.Length;
for(int i = 0; i < len; i++)
{
for (int j = 0; j < len - i; j++)
{
bool found = true;
for (int k = j; k < (len - j) / 2; k++)
{
if (s[k] != s[len - (k - j + 1)])
{
found = false;
break;
}
}
if (found)
{
if (len - j > maxLengthPalindrome.Length)
maxLengthPalindrome = s.Substring(j, len - j);
}
if(maxLengthPalindrome.Length >= (len - (i + j)))
break;
}
if (maxLengthPalindrome.Length >= (len - i))
break;
}
return maxLengthPalindrome;
}
I got this question when i took an interview.
I found out when i was back home, unfortunately.
public static string GetMaxPalindromeString(string testingString)
{
int stringLength = testingString.Length;
int maxPalindromeStringLength = 0;
int maxPalindromeStringStartIndex = 0;
for (int i = 0; i < testingString.Length; i++)
{
int currentCharIndex = i;
for (int lastCharIndex = stringLength - 1; lastCharIndex > currentCharIndex; lastCharIndex--)
{
bool isPalindrome = true;
if (testingString[currentCharIndex] != testingString[lastCharIndex])
{
continue;
}
for (int nextCharIndex = currentCharIndex + 1; nextCharIndex < lastCharIndex / 2; nextCharIndex++)
{
if (testingString[nextCharIndex] != testingString[lastCharIndex - 1])
{
isPalindrome = false;
break;
}
}
if (isPalindrome)
{
if (lastCharIndex + 1 - currentCharIndex > maxPalindromeStringLength)
{
maxPalindromeStringStartIndex = currentCharIndex;
maxPalindromeStringLength = lastCharIndex + 1 - currentCharIndex;
}
}
break;
}
}
return testingString.Substring(maxPalindromeStringStartIndex, maxPalindromeStringLength);
}