Find coins which sum to target amount with a restricted set - dynamic-programming

Given a sum amount 1.15 Rs. (1 Rs. = 100 Paise), so total 115 paise and given a list of 8 coins with denominations as {1, 2, 5, 10, 20, 25, 50, 100} paise. Find 6 coins which sum to 1.15 Rs. The constraint is that I should not be able to give change from my solution for the amounts given in a restricted set. The restricted set here is {5, 10, 20, 25}.
Appreciate any solutions or pointers.

Is this what you are looking for?
import java.util.Arrays;
public class Coining {
public static void getChange(int amount, int[] denomination){
Arrays.sort(denomination);//sort the array
for(int coin=denomination.length-1; coin>=0;coin--){
int coef = amount/denomination[coin];
amount%=denomination[coin];
if(coef > 0)
System.out.format("%d {%d Paise}%n",coef, denomination[coin]);
if(amount == 0)
return;
}
}//
public static void main(String... args){
//int coins[]={1,2,5,10,20,25,50,100}; THIS IS IRRELEVANT.
int restricted[]={5,10,20,25};
int amount = 115;
getChange(amount,restricted);
}//
}

Related

What is the format of the timestamp in InstallShield's ISString table?

I was recently trying to determine the answer to this question. The only post I was able to find on the topic was this old unanswered post on Flexera's website.
I wanted to know the answer to this question to incorporate in a tool for managing string translations. I already discovered the answer (my coworker and I spent the better half of our day trying to figure it out) but I thought I'd post the question/answer on Stack Overflow just in case someone else searches for it.
The answer is that the timestamp is a 32-bit integer with different bits representing different parts of the date.
Here's how it breaks down
Bits 1-5 : The Day of the Month [1-31] (end range could be 28-31 depending on month)
Bits 6-9 : The Month [1-12]
Bits 10-16: The Year after 1980 (only goes to year 2107) [0-127]
Bits 17-21: (?) Seconds rounded to even (only 5 bits so can only contain 31 values) [0-30]
Bits 22-27: Minutes [0-59]
Bits 28-32: Hours from 12 AM [0-23]
If the 32-bit integer is an invalid date it's evaluated to a default date Dec/30/1899 12:00 AM
Here is an example:
-------BINARY-32-bit-Integer----- | Decimal | Date String
DOM Month Year Seconds*2 Min Hour | |
00111 0111 0010000 00001 010000 00000 | 999295488 | Jul/07/1996 12:16 AM
7 7 16 1 16 0
Here is some C# code written to convert between DateTime and the string representation of the ISString timestamp (Small Disclaimer: this code doesn't currently handle invalid timestamp input):
private static int bitsPerDOM = 5;
private static int bitsPerMonth = 4;
private static int bitsPerYear = 7;
private static int bitsPerEvenSecond = 5;
private static int bitsPerMinute = 6;
private static int bitsPerHour = 5;
private static int startYear = 1980;
public static string getISTimestamp(DateTime date)
{
int[] shiftValues = { bitsPerDOM, bitsPerMonth, bitsPerYear, bitsPerEvenSecond, bitsPerMinute, bitsPerHour };
int[] dateValues = { date.Day, date.Month, date.Year -startYear, date.Second/2, date.Minute, date.Hour };
int shift = 32;
int dateInt = 0;
for (int i = 0; i < dateValues.Length; i++)
{
shift -= shiftValues[i];
dateInt |= (dateValues[i] << shift);
}
return dateInt.ToString();
}
public static DateTime getTimeFromISTimestampStr(string ISTimestampStr)
{
int timestampInt = Int32.Parse(ISTimestampStr);
int dom = getBits(timestampInt, 0, 4);
int month = getBits(timestampInt, 5, 8);
int year = startYear + getBits(timestampInt, 9, 15);
int seconds = getBits(timestampInt, 16, 20) * 2;
int minutes = getBits(timestampInt, 21, 26);
int hours = getBits(timestampInt, 27, 31);
return new DateTime(year, month, dom, hours, minutes, seconds);
}
private static int getBits(int n, int start, int end)
{
//Clear left bits by shifting
n <<= start;
n >>= 31 + start - end; //Shift to the right
return n;
}

How to find the biggest number in a string that contains not just numbers but words?

How to find the biggest number in a string that contains not just numbers but words?
For example:
String naa = "John 19, Reuben 21, sbu 6, Derick 33";
I need to be able to find the highest age no mater the names and ages entered.
I'm not sure what language you are trying to use but one way to do this in ruby for example would be
str = "John 19, Reuben 21, sbu 6, Derick 33;"
str.gsub(/\d+/).map { |i| i.to_i }.max
What this does is the following:
str.gsub(/\d+/)
Returns all the numbers as an enumerator
The map command then changes them all to integers and returns an Array with the integers.
Then we just call max on that array.
Java
String[] ss = "John 19, Reuben 21, sbu 6, Derick 33;".split("[^\\d]");
System.out.println(Arrays.asList(ss));
int max = Integer.MIN_VALUE;
for(String s:ss){
try{
if (Math.max(Integer.valueOf(s), max) != max){
max = Integer.valueOf(s);
}
}catch(NumberFormatException nfe){}
}
System.out.println(max);
Try this in java
Pattern p = Pattern.compile("[0-9]?[0-9]");
Matcher m = p.matcher(naa) ;
List<Integer> listInt = new ArrayList<Integer>();
while (m.find()) {
int age = Integer.parseInt(m.group());
listInt.add(age);
}
int max = Collections.max(listInt);
System.out.println( max);

Random number in long range, is this the way?

Can somebody verify this method. I need a long type number inside a range of two longs. I use the .NET Random.Next(min, max) function which return int's. Is my reasoning correct if I simply divide the long by 2, generate the random number and finally multiply it by 2 again? Or am I too enthusiastic...
I understand that my random resolution will decrease but are there any other mistakes which will lead to no such a random number.
long min = st.MinimumTime.Ticks; //long is Signed 64-bit integer
long max = st.MaximumTime.Ticks;
int minInt = (int) (min / 2); //int is Signed 64-bit integer
int maxInt = (int) (max / 2); //int is Signed 64-bit integer
Random random = new Random();
int randomInt = random.Next(minInt, maxInt);
long randomLong = (randomInt * 2);
Why don't you just generate two random Int32 values and make one Int64 out of them?
long LongRandom(long min, long max, Random rand) {
long result = rand.Next((Int32)(min >> 32), (Int32)(max >> 32));
result = (result << 32);
result = result | (long)rand.Next((Int32)min, (Int32)max);
return result;
}
Sorry, I forgot to add boundaries the first time. Added min and max params. You can test it like that:
long r = LongRandom(100000000000000000, 100000000000000050, new Random());
Values of r will lie in the desired range.
EDIT: the implementation above is flawed. It's probably worth it to generate 4 16-bit integers rather than 2 32-bit ones to avoid signed-unsigned problems. But at this point the solution loses its elegancy, so I think it's best to stick with Random.NextBytes version:
long LongRandom(long min, long max, Random rand) {
byte[] buf = new byte[8];
rand.NextBytes(buf);
long longRand = BitConverter.ToInt64(buf, 0);
return (Math.Abs(longRand % (max - min)) + min);
}
It looks pretty well in terms of value distribution (judging by very simple tests I ran).
Some other answers here have two issues: having a modulo bias, and failing to correctly handle values of max = long.MaxValue. (Martin's answer has neither problem, but his code is unreasonably slow with large ranges.)
The following code will fix all of those issues:
//Working with ulong so that modulo works correctly with values > long.MaxValue
ulong uRange = (ulong)(max - min);
//Prevent a modolo bias; see https://stackoverflow.com/a/10984975/238419
//for more information.
//In the worst case, the expected number of calls is 2 (though usually it's
//much closer to 1) so this loop doesn't really hurt performance at all.
ulong ulongRand;
do
{
byte[] buf = new byte[8];
random.NextBytes(buf);
ulongRand = (ulong)BitConverter.ToInt64(buf, 0);
} while (ulongRand > ulong.MaxValue - ((ulong.MaxValue % uRange) + 1) % uRange);
return (long)(ulongRand % uRange) + min;
The following fully-documented class can be dropped into your codebase to implement the above solution easily and brain-free. Like all code on Stackoverflow, it's licensed under CC-attribution, so you can feel free to use to use it for basically whatever you want.
using System;
namespace MyNamespace
{
public static class RandomExtensionMethods
{
/// <summary>
/// Returns a random long from min (inclusive) to max (exclusive)
/// </summary>
/// <param name="random">The given random instance</param>
/// <param name="min">The inclusive minimum bound</param>
/// <param name="max">The exclusive maximum bound. Must be greater than min</param>
public static long NextLong(this Random random, long min, long max)
{
if (max <= min)
throw new ArgumentOutOfRangeException("max", "max must be > min!");
//Working with ulong so that modulo works correctly with values > long.MaxValue
ulong uRange = (ulong)(max - min);
//Prevent a modolo bias; see https://stackoverflow.com/a/10984975/238419
//for more information.
//In the worst case, the expected number of calls is 2 (though usually it's
//much closer to 1) so this loop doesn't really hurt performance at all.
ulong ulongRand;
do
{
byte[] buf = new byte[8];
random.NextBytes(buf);
ulongRand = (ulong)BitConverter.ToInt64(buf, 0);
} while (ulongRand > ulong.MaxValue - ((ulong.MaxValue % uRange) + 1) % uRange);
return (long)(ulongRand % uRange) + min;
}
/// <summary>
/// Returns a random long from 0 (inclusive) to max (exclusive)
/// </summary>
/// <param name="random">The given random instance</param>
/// <param name="max">The exclusive maximum bound. Must be greater than 0</param>
public static long NextLong(this Random random, long max)
{
return random.NextLong(0, max);
}
/// <summary>
/// Returns a random long over all possible values of long (except long.MaxValue, similar to
/// random.Next())
/// </summary>
/// <param name="random">The given random instance</param>
public static long NextLong(this Random random)
{
return random.NextLong(long.MinValue, long.MaxValue);
}
}
}
Usage:
Random random = new Random();
long foobar = random.NextLong(0, 1234567890L);
This creates a random Int64 by using random bytes, avoiding modulo bias by retrying if the number is outside the safe range.
static class RandomExtensions
{
public static long RandomLong(this Random rnd)
{
byte[] buffer = new byte[8];
rnd.NextBytes (buffer);
return BitConverter.ToInt64(buffer, 0);
}
public static long RandomLong(this Random rnd, long min, long max)
{
EnsureMinLEQMax(ref min, ref max);
long numbersInRange = unchecked(max - min + 1);
if (numbersInRange < 0)
throw new ArgumentException("Size of range between min and max must be less than or equal to Int64.MaxValue");
long randomOffset = RandomLong(rnd);
if (IsModuloBiased(randomOffset, numbersInRange))
return RandomLong(rnd, min, max); // Try again
else
return min + PositiveModuloOrZero(randomOffset, numbersInRange);
}
static bool IsModuloBiased(long randomOffset, long numbersInRange)
{
long greatestCompleteRange = numbersInRange * (long.MaxValue / numbersInRange);
return randomOffset > greatestCompleteRange;
}
static long PositiveModuloOrZero(long dividend, long divisor)
{
long mod;
Math.DivRem(dividend, divisor, out mod);
if(mod < 0)
mod += divisor;
return mod;
}
static void EnsureMinLEQMax(ref long min, ref long max)
{
if(min <= max)
return;
long temp = min;
min = max;
max = temp;
}
}
Here is a solution that leverages from the other answers using Random.NextBytes, but also pays careful attention to boundary cases. I've structured it as a set of extension methods. Also, I've accounted for modulo bias, by sampling another random number it falls out of range.
One of my gripes (at least for the situation I was trying to use it) is that the maximum is usually exclusive so if you want to roll a die, you do something like Random.Next(0,7). However, this means you can never get this overload to return the .MaxValue for the datatype (int, long, ulong, what-have-you). Therefore, I've added an inclusiveUpperBound flag to toggle this behavior.
public static class Extensions
{
//returns a uniformly random ulong between ulong.Min inclusive and ulong.Max inclusive
public static ulong NextULong(this Random rng)
{
byte[] buf = new byte[8];
rng.NextBytes(buf);
return BitConverter.ToUInt64(buf, 0);
}
//returns a uniformly random ulong between ulong.Min and Max without modulo bias
public static ulong NextULong(this Random rng, ulong max, bool inclusiveUpperBound = false)
{
return rng.NextULong(ulong.MinValue, max, inclusiveUpperBound);
}
//returns a uniformly random ulong between Min and Max without modulo bias
public static ulong NextULong(this Random rng, ulong min, ulong max, bool inclusiveUpperBound = false)
{
ulong range = max - min;
if (inclusiveUpperBound)
{
if (range == ulong.MaxValue)
{
return rng.NextULong();
}
range++;
}
if (range <= 0)
{
throw new ArgumentOutOfRangeException("Max must be greater than min when inclusiveUpperBound is false, and greater than or equal to when true", "max");
}
ulong limit = ulong.MaxValue - ulong.MaxValue % range;
ulong r;
do
{
r = rng.NextULong();
} while(r > limit);
return r % range + min;
}
//returns a uniformly random long between long.Min inclusive and long.Max inclusive
public static long NextLong(this Random rng)
{
byte[] buf = new byte[8];
rng.NextBytes(buf);
return BitConverter.ToInt64(buf, 0);
}
//returns a uniformly random long between long.Min and Max without modulo bias
public static long NextLong(this Random rng, long max, bool inclusiveUpperBound = false)
{
return rng.NextLong(long.MinValue, max, inclusiveUpperBound);
}
//returns a uniformly random long between Min and Max without modulo bias
public static long NextLong(this Random rng, long min, long max, bool inclusiveUpperBound = false)
{
ulong range = (ulong)(max - min);
if (inclusiveUpperBound)
{
if (range == ulong.MaxValue)
{
return rng.NextLong();
}
range++;
}
if (range <= 0)
{
throw new ArgumentOutOfRangeException("Max must be greater than min when inclusiveUpperBound is false, and greater than or equal to when true", "max");
}
ulong limit = ulong.MaxValue - ulong.MaxValue % range;
ulong r;
do
{
r = rng.NextULong();
} while(r > limit);
return (long)(r % range + (ulong)min);
}
}
private long randomLong()
{
Random random = new Random();
byte[] bytes = new byte[8];
random.NextBytes(bytes);
return BitConverter.ToInt64(bytes, 0);
}
This will get you a secure random long:
using (RNGCryptoServiceProvider rg = new RNGCryptoServiceProvider())
{
byte[] rno = new byte[9];
rg.GetBytes(rno);
long randomvalue = BitConverter.ToInt64(rno, 0);
}
Start at the minimum, add a random percentage of the difference between the min and the max. Problem with this is that NextDouble returns a number x such that 0 <= x < 1, so there's a chance you'll never hit the max number.
long randomLong = min + (long)(random.NextDouble() * (max - min));
Your randomLong will always be even and you will have eliminated even more values because you are very far away from the maximum for long, The maximum for long is 2^32 * max for int. You should use Random.NextBytes.
You can try CryptoRandom of the Inferno library:
public class CryptoRandom : Random
// implements all Random methods, as well as:
public byte[] NextBytes(int count)
public long NextLong()
public long NextLong(long maxValue)
public long NextLong(long minValue, long maxValue)
I wrote some Test Methods and check my own method and many of the answers from this and the same questions. Generation of redundant values is a big problem. I found #BlueRaja - Danny Pflughoeft answer at this address Is good enough and did not generate redundant values at least for first 10,000,000s. This is a Test Method:
[TestMethod]
public void TestRand64WithExtensions()
{
Int64 rnum = 0;
HashSet<Int64> hs = new HashSet<long>();
Random randAgent = new Random((int)DateTime.Now.Ticks);
for (int i = 0; i < 10000000; i++)
{
rnum = randAgent.NextLong(100000000000000, 999999999999999);
//Test returned value is greater than zero
Assert.AreNotEqual(0, rnum);
//Test Length of returned value
Assert.AreEqual(15, rnum.ToString().Length);
//Test redundancy
if (!hs.Contains(rnum)) { hs.Add(rnum); }
else
{
//log redundant value and current length we received
Console.Write(rnum + " | " + hs.Count.ToString());
Assert.Fail();
}
}
}
I didn't want to post this as an answer but I can't stuff this in the comment section and I didn't want to add as an edit to answer without author consent. So pardon me as this is not an independent answer and maybe just a prove to one of the answers.
I wrote a benchmarking C# console app that tests 5 different methods for generating unsigned 64-bit integers. Some of those methods are mentioned above. Method #5 appeared to consistently be the quickest. I claim to be no coding genius, but if this helps you, you're welcome to it. If you have better ideas, please submit. - Dave (sbda26#gmail.com)
enter code here
static private Random _clsRandom = new Random();
private const int _ciIterations = 100000;
static void Main(string[] args)
{
RunMethod(Method1);
RunMethod(Method2);
RunMethod(Method3);
RunMethod(Method4);
RunMethod(Method5);
Console.ReadLine();
}
static void RunMethod(Func<ulong> MethodX)
{
ulong ulResult;
DateTime dtStart;
TimeSpan ts;
Console.WriteLine("--------------------------------------------");
Console.WriteLine(MethodX.Method.Name);
dtStart = DateTime.Now;
for (int x = 1; x <= _ciIterations; x++)
ulResult = MethodX.Invoke();
ts = DateTime.Now - dtStart;
Console.WriteLine(string.Format("Elapsed time: {0} milliseconds", ts.TotalMilliseconds));
}
static ulong Method1()
{
int x1 = _clsRandom.Next(int.MinValue, int.MaxValue);
int x2 = _clsRandom.Next(int.MinValue, int.MaxValue);
ulong y;
// lines must be separated or result won't go past 2^32
y = (uint)x1;
y = y << 32;
y = y | (uint)x2;
return y;
}
static ulong Method2()
{
ulong ulResult = 0;
for(int iPower = 0; iPower < 64; iPower++)
{
double dRandom = _clsRandom.NextDouble();
if(dRandom > 0.5)
{
double dValue = Math.Pow(2, iPower);
ulong ulValue = Convert.ToUInt64(dValue);
ulResult = ulResult | ulValue;
}
}
return ulResult;
}
static ulong Method3() // only difference between #3 and #2 is that this one (#3) uses .Next() instead of .NextDouble()
{
ulong ulResult = 0;
for (int iPower = 0; iPower < 64; iPower++)
if (_clsRandom.Next(0, 1) == 1)
ulResult = ulResult | Convert.ToUInt64(Math.Pow(2, iPower));
return ulResult;
}
static ulong Method4()
{
byte[] arr_bt = new byte[8];
ulong ulResult;
_clsRandom.NextBytes(arr_bt);
ulResult = BitConverter.ToUInt64(arr_bt, 0);
return ulResult;
}
// Next method courtesy of https://stackoverflow.com/questions/14708778/how-to-convert-unsigned-integer-to-signed-integer-without-overflowexception/39107847
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit)]
struct EvilUnion
{
[System.Runtime.InteropServices.FieldOffset(0)] public int Int32;
[System.Runtime.InteropServices.FieldOffset(0)] public uint UInt32;
}
static ulong Method5()
{
var evil = new EvilUnion();
ulong ulResult = 0;
evil.Int32 = _clsRandom.Next(int.MinValue, int.MaxValue);
ulResult = evil.UInt32;
ulResult = ulResult << 32;
evil.Int32 = _clsRandom.Next(int.MinValue, int.MaxValue);
ulResult = ulResult | evil.UInt32;
return ulResult;
}
}
I'll add my solution for generating random unsigned long integer (random ulong) below max value.
public static ulong GetRandomUlong(ulong maxValue)
{
Random rnd = new Random();
//This algorithm works with inclusive upper bound, but random generators traditionally have exclusive upper bound, so we adjust.
//Zero is allowed, function will return zero, as well as for 1. Same behavior as System.Random.Next().
if (maxValue > 0) maxValue--;
byte[] maxValueBytes = BitConverter.GetBytes(maxValue);
byte[] result = new byte[8];
int i;
for(i = 7; i >= 0; i--)
{
//senior bytes are either zero (then Random will write in zero without our help), or equal or below that of maxValue
result[i] = (byte)rnd.Next( maxValueBytes[i] + 1 );
//If, going high bytes to low bytes, we got ourselves a byte, that is lower than that of MaxValue, then lower bytes may be of any value.
if ((uint)result[i] < maxValueBytes[i]) break;
}
for(i--; i >= 0; i--) // I like this row
{
result[i] = (byte)rnd.Next(256);
}
return BitConverter.ToUInt64(result, 0);
}
C#10 now has long randoms built in.
Use NextInt64 if you can.
You're better off taking the difference between minimum and maximum (if it fits in an int), getting a random between 0 and that, and adding it to the minimum.
Is there anything wrong with using this simple approach?
long min = 10000000000001;
long max = 99999999999999;
Random random = new Random();
long randomNumber = min + random.Next() % (max - min);
d
My worked solution. Tested for 1000+ times:
public static long RandomLong(long min, long max)
{
return min + (long)RandomULong(0, (ulong)Math.Abs(max - min));
}
public static ulong RandomULong(ulong min, ulong max)
{
var hight = Rand.Next((int)(min >> 32), (int)(max >> 32));
var minLow = Math.Min((int)min, (int)max);
var maxLow = Math.Max((int)min, (int)max);
var low = (uint)Rand.Next(minLow, maxLow);
ulong result = (ulong)hight;
result <<= 32;
result |= (ulong)low;
return result;
}
How about generating bytes and converting to int64?
/* generate a byte array, then convert to unint64 */
var r = new Random(); // DONT do this for each call - use a static Random somewhere
var barray = new byte[64/8];
r.NextBytes(barray);
var rint64 = BitConverter.ToUInt64(barray, 0);
Sees to work for me (:
What's wrong with generating a double to be intended as a factor to be used to calculate the actual long value starting from the max value a long can be?!
long result = (long)Math.Round( random.NextDouble() * maxLongValue );
NextDouble generates a random number between [0.0, 0.99999999999999978] (msdn doc)
You multiply this random number by your maxLongValue.
You Math.Round that result so you can get the chance to get maxLongValue anyway (eg: simulate you got 1.0 from the NextDouble).
You cast back to long.

How do I convert a string version of a number in an arbitrary base to an integer?

how to convert string to integer??
for ex:
"5328764",to int base 10
"AB3F3A", to int base 16
any code will be helpfull
Assuming arbitrary base (not 16, 10, 8, 2):
In C (C++), use strtol
return strtol("AB3F3A", NULL, 16);
In Javascript, use parseInt.
return parseInt("AB3F3A", 16);
In Python, use int(string, base).
return int("AB3F3A", 16)
In Java, use Integer.parseInt (thanks Michael.)
return Integer.parseInt("AB3F3A", 16);
In PHP, use base_convert.
return intval(base_convert('AB3F3A', 16, 10));
In Ruby, use to_i
"AB3F3A".to_i(16)
In C#, write one yourself.
in C#, i think it is: Convert.ToInt64(value, base)
and the base must be 2, 8, 10, or 16
9999 is really 9000 + 900 + 90 + 9
So, start at the right hand side of the string, and pick off the numbers one at a time.
Each character number has an ASCII code, which can be translated to the number, and multiplied by the appropriate amount.
Two functions in java, in both directions: "code" parameter represent the numerical system: "01" for base 2, "0123456789" for base 10, "0123456789abcdef" for hexdecimal and so on...
public String convert(long num, String code) {
final int base = code.length();
String text = "";
while (num > 0) {
text = code.charAt((int) (num%base)) + text;
num /= base;
}
return text;
}
public long toLong(String text, String code) {
final long base = code.length();
long num = 0;
long pow = 1;
int len = text.length();
for(int i = 0; i < len; i++) {
num += code.indexOf(text.charAt(len - i - 1)) * pow;
pow *= base;
}
return num;
}
println(convert(9223372036854775807L,"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"));
println(convert(9223372036854775807L,"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ#=-+*/^%$#&()!?.,:;[]"));
println(toLong("Ns8T$87=uh","0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ#=-+*/^%$#&()!?.,:;[]"));```
in your example:
toLong("5328764", "0123456789") = 5328764
toLong("AB3F3A", "0123456789ABCDEF") = 11222842

String unique characters [duplicate]

This question already has answers here:
Determining a string has all unique characters without using additional data structures and without the lowercase characters assumption
(7 answers)
Closed 8 years ago.
Implement an algorithm to determine if a string has all unique characters. What if you can not use additional data structures?
If you can use a little auxiliary memory, then a small array of bits (indexed by the numerical code of the character) is all you need (if your characters are 4-byte Unicode ones you'll probably want a hashmap instead;-). Start with all bits at 0: scan the string from the start -- each time, you've found a duplicate if the bit corresponding to the current character is already 1 -- otherwise, no duplicates yet, set that bit to 1. This is O(N).
If you can't allocate any extra memory, but can alter the string, sorting the string then doing a pass to check for adjacent duplicates is the best you can do, O(N log N).
If you can't allocate extra memory and cannot alter the string, you need an O(N squared) check where each character is checked vs all the following ones.
we can do it by assigning a prime number to every character.. and multiply it for every character found. then on every character check that if the value is divisible by the number assigned to that character or not..
answer in c program
int is_uniq(char *str)
{
int i = 0, flag = 0, value = 0;
for(i = 0; i < strlen(str); i++) {
value = str[i] - 'a';
if(flag & (1 << value)) {
return 0;
}
flag |= (1 << value);
}
return 1;
}
for each character in the string
if any subsequent character matches it
fail
succeed
One possible solution - You could extract the string into an array of characters, sort the array, and then loop over it, checking to see if the next character is equal to the current one.
the prime method described by partik (based on this theorem). It's O(N).
# one prime per letter
primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101]
starting_byte = ?a.ord
primes_product = 1
ARGV[0].each_byte do |byte|
current_prime = primes[byte - starting_byte]
if primes_product % current_prime == 0
puts "Not unique"
exit
else
primes_product = primes_product * current_prime
end
end
puts "Unique"
I came on this thread for the similar question and ended up with the following solution in C#:
var data = "ABCDEFGADFGHETFASAJUTE";
var hash = new Dictionary<char, int>();
foreach (char c in data)
{
if (hash.ContainsKey(c))
{
hash[c] += 1;
}
else
{
hash.Add(c, 1);
}
}
var Characters = hash.Keys.ToArray();
var Frequencies = hash.Values.ToArray();
import java.io.*;
public class uniqueChar
{
boolean checkUniqueChar(String strin)
{
int m;
char []str=strin.toCharArray();
java.util.Arrays.sort(str);
for(int i=0;i<str.length-1;i++)
{
if(str[i]==str[i+1])
return false;
}
return true;
}
public static void main(String argv[]) throws IOException
{
String str;
System.out.println("enter the string\n");
InputStreamReader in=new InputStreamReader(System.in);
BufferedReader bin=new BufferedReader(in);
str=bin.readLine();
System.out.println(new uniqueChar().checkUniqueChar(str));
}
}
public static boolean isUniqueChars(String str) {
int checker = 0;
for (int i = 0; i < str.length(); ++i) {
int val = str.charAt(i) - 'a';
if ((checker & (1 << val)) > 0)
return false;
checker |= (1 << val);
}
return true;
}

Resources