Speed up the comparison time of two strings - java

The task is to write the logic of checking the magnitude of the coincidence of the player's attempt with the hidden word.
More formally, let there be a string S — a hidden word and a string Q — a player's attempt.
Both strings have the same length N. For each position 1 ≤ i ≤ N of string Q, we need to calculate the type of match in this position with string S.
If Q[i] = S[i], then at position i the match type should be equal to "correct".
If Q[i]≠S[i], but there is another position 1 ≤ j≤ N such that Q[i] = S[j], then in position i the match type must be equal to "present".
Each letter of the string S can be used in no more than one match of
the type "correct" or "present".
Priority is always given to the "correct" type.
Of all possible use cases in the "present" type, the program selects
the leftmost position in the Q string.
In other positions, the match type must be equal to "absent".
Input format:
The first line contains the string S (1≤ S ≤ 10^6) — the hidden word.
The second line contains the string Q ( Q = S) — the player's attempt.
It is guaranteed that the strings S and Q contain only uppercase Latin letters.
Example:
input:
COVER
CLEAR
output:
correct
absent
present
absent
correct
My program does this very slowly, how can I speed it up?
import java.util.*;
public class Task1 {
private final static String cor = "correct";
private final static String abs = "absent";
private final static String pre = "present";
static String[] stringArr;
static java.util.Map<Integer, Integer> map = new HashMap<>();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String a = sc.nextLine();
String b = sc.nextLine();
stringArr = new String[a.length()];
int length1 = a.length();
char[] arr1 = a.toCharArray();
char[] arr2 = b.toCharArray();
for (int i = 0; i < length1; i++) {
if (arr2[i] == arr1[i]) {
stringArr[i] = cor;
map.put(i, i);
}
}
for (int i = 0; i < length1; i++) {
if (arr2[i] != arr1[i]) {
while (stringArr[i] == null) {
boolean finded = false;
for (int j = 0; j < arr1.length; j++) {
if (arr2[i] == arr1[j] && !map.containsKey(j)) {
stringArr[i] = pre;
finded = true;
map.put(j, j);
break;
}
}
if (!finded) stringArr[i] = abs;
}
}
}
for (String s : stringArr) {
System.out.println(s);
}
}
}

You can use an int array (or a HashMap<Char, Integer>) count to store those "presented" characters.
We need two for loops. The first loop will set all "correct" positions (if arr1[i] == arr2[i], then stringArr[i] = cor); and for those unmatched positions (arr1[i] != arr2[i]), we count the number of occurrences for those characters in the hidden word (count[arr1[i] - 'A']++).
Then in the second for loop, we check those unmatched positions with the help of count.
If count[arr2[i] - 'A'] > 0, it means that the hidden word contains the character arr2[i], so we can set stringArr[i] = pre and decrement count[arr2[i] - 'A'] (since each letter can be used once)
Otherwise, there's no matching letter in the hidden word, stringArr[i] should be set to abs.
import java.util.Scanner;
public class Task1 {
private final static String cor = "correct";
private final static String abs = "absent";
private final static String pre = "present";
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String a = sc.nextLine();
String b = sc.nextLine();
String[] stringArr = new String[a.length()];
int length1 = a.length();
char[] arr1 = a.toCharArray();
char[] arr2 = b.toCharArray();
int[] count = new int[26];
for (int i = 0; i < length1; i++) {
if (arr2[i] == arr1[i]) {
stringArr[i] = cor;
}
else {
count[arr1[i] - 'A']++;
}
}
for (int i = 0; i < length1; i++) {
if (arr1[i] != arr2[i]) {
if (count[arr2[i] - 'A'] > 0) {
stringArr[i] = pre;
count[arr2[i] - 'A']--;
}
else {
stringArr[i] = abs;
}
}
}
for (String s : stringArr) {
System.out.println(s);
}
}
}

This can be done using hashmaps and taking advantage of the o(1) insert/delete time.
I'm assuming that each word is exactly the same length. Consequently, to get the answer, we need to check each letter in each word. If they have a length of n, then that means at a minimum it will take o(2n) == o(n) to find the answer.
[1] Then, if you're able to use extra space, I would just use a hashmap as an index, where the key is a character in secret, and the value is the set of indices that letter occurs in secret. So it would look something like this:
//cover
c:<0>
o:<1>
etx...
[2] Then check each letter in guess against the index.
If there is no key for a letter, the put absent
If there is a key, then look in the set of indices to see if there is a matching index. Since I used a hashset, that's another o(1) lookup
So sum total, you walk through secret and guess once each which is o(n) runtime. That, plus o(1) for each index lookup produces o(n) runtime.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
public class Task1 {
public static void main(String[] args)
{
ArrayList<String> res = solve("COVER", "CLEAR");
System.out.println(res);
}
public static ArrayList<String> solve(String secret, String guess){
ArrayList<String> result = new ArrayList<>();
HashMap<Character, HashSet<Integer>> index = new HashMap<>();
//shortcut
if(secret.equals(guess)){
for(int i = 0; i < secret.length(); i++) result.add("correct");
return result;
}
//make the index of char:<indices> for the chars in "secret"
for(int i = 0; i < secret.length(); i++){
char c = secret.charAt(i);
HashSet<Integer> bucket = index.get(c);
if(bucket == null){
bucket = new HashSet<>();
index.put(c, bucket);
}
bucket.add(i);
}
//check each char in "guess" against the index and tally the result
for(int i = 0; i < guess.length(); i++){
char c = guess.charAt(i);
HashSet<Integer> bucket = index.get(c);
if(bucket == null) result.add("absent");
else if(bucket.contains(i)) result.add("correct");
else result.add("present");
}
return result;
}
}

Related

Anagrams in java

package intials;
public class Anagrams {
public static void main(String[] args) {
String a = "cat";
String b = "act";
boolean isAnagram = false;
for (int i = 0; i < a.length(); i++) {
char c = a.charAt(i);
isAnagram = false;
for (int j = 0; j < b.length(); j++) {
if (b.charAt(j) == c) {
isAnagram = true;
break;
}
}
if (!isAnagram) {
break;
}
}
if (isAnagram) {
System.out.println("is anagram");
} else {
System.out.println("is not anagram");
}
}
}
Please tell me what is wrong in this code.
Also tell me what should be the changes should I make
A easy way to check if two words are anagram is to transform them in array, sort them and compare.
public boolean areAnagram(string str1, string str2)
{
// Transform strings in arrays
String[] arr1 = str1.split("");
String[] arr2 = str2.split("");
// Check if they have the same length
if (arr1.length != arr2.length)
return false;
// Sort array
Arrays.sort(arr1);
Arrays.sort(arr2);
// Compare value
for (int i = 0; i < arr1.length; i++)
if (arr1[i] != arr2[i])
return false;
return true;
}
boolean test = areAnagram("toto", "otot");
This is comparatively better for large characters range :
static boolean isAnagram(String text1, String text2){
if (text1.length() != text2.length())
return false;
// If you want to ignore case sensitivity of characters
text1 = text1.toLowerCase();
text2 = text2.toLowerCase();
Set<Character> set1 = new HashSet();
Set<Character> set2 = new HashSet();
for (int i = 0; i < text1.length(); i++) {
set1.add(text1.charAt(i));
set2.add(text2.charAt(i));
}
return set1.equals(set2);
}
First, the anagrams should have equal lengths, if this condition is not met, the words are not anagrams.
Next, as mentioned in the comments, not only the characters but their frequencies should be compared, that is, a map Map<Character, Integer> needs to be created containing frequency of each character in a string.
For one string the frequencies may be counted with + sign, and for the other with - sign. If all values in the map are 0, the words are anagrams.
The implementation may look as follows (using Map::merge to calculate frequencies and Stream::allMatch to detect the anagram):
public static boolean isAnagram(String a, String b) {
if (a.length() != b.length()) {
return false;
}
Map<Character, Integer> frequencies = new HashMap<>();
for (int i = 0, n = a.length(); i < n; i++) {
frequencies.merge(Character.toLowerCase(a.charAt(i)), 1, Integer::sum);
frequencies.merge(Character.toLowerCase(b.charAt(i)), -1, Integer::sum);
}
return frequencies.values().stream().allMatch(x -> x == 0);
}
Tests
String[][] tests = {
{"act", "tact"},
{"acta", "tact"},
{"Raca", "arca"}
};
for(String[] t : tests) {
System.out.printf("Are '%s' and '%s' anagrams? %s%n", t[0], t[1], isAnagram(t[0], t[1]));
}
Output
Are 'act' and 'tact' anagrams? false
Are 'acta' and 'tact' anagrams? false
Are 'Raca' and 'arca' anagrams? true
This solution is faster with the time complexity of O(n). However, it needs extra space for the counting array. At 256 integers, for ASCII that's not too bad. But increasing CHARACTER_RANGE to support multiple-byte character sets such as UTF-8, this would become very memory hungry. Therefore, it's only really practical when the number of possible characters is in a small range.
class Anagram {
static int CHARACTER_RANGE= 256;
static boolean isAnagram(String text1, String text2){
if (text1.length() != text2.length())
return false;
// if want to consider case sensitivity of char
//char str1[] = text1.toCharArray();
//char str2[] = text2.toCharArray();
// if don't want to consider case sensitivity of char
char str1[] = text1.toLowerCase().toCharArray();
char str2[] = text2.toLowerCase().toCharArray();
int count1[] = new int[CHARACTER_RANGE];
Arrays.fill(count1, 0);
int count2[] = new int[CHARACTER_RANGE];
Arrays.fill(count2, 0);
int i;
for (i = 0; i < str1.length && i < str2.length; i++) {
count1[str1[i]]++;
count2[str2[i]]++;
}
for (i = 0; i < CHARACTER_RANGE; i++)
if (count1[i] != count2[i])
return false;
return true;
}
}

Replacing String in Java to get all variations

I'm trying to get a printout of all variations of a certain String. For example, we have this input: AB0C0. The 0 in the 3rd and 5th spots should be treated as variables. The variable characters are 1, 2, and 3 to be placed in the spot of 0. This means there would be all possible variations of this input:
AB1C1
AB2C1
AB3C1
AB1C2
AB1C3
AB2C2
AB2C3
AB3C2
AB3C3
This is just an example. A 5-character long string is a place for 1 to 5 variables. The issue I'm facing is, that it should generate all variations no matter how many variables are in the input in no matter in which place they are.
Scanner scanner = new Scanner (System.in);
System.out.println("Enter the key consisting of 5 characters:");
String input = scanner.next();
String strOutput1 = input.replaceFirst("0","1");
String strOutput1A = input.replace("0","1");
String strOutput2 = input.replaceFirst("0","2");
String strOutput3 = input.replaceFirst("0","3");
String strOutput4 = input.replaceFirst("0","4");
String strOutput5 = input.replaceFirst("0","5");
System.out.println(strOutput1.toUpperCase());
System.out.println(strOutput1A.toUpperCase());
System.out.println(strOutput2.toUpperCase());
System.out.println(strOutput3.toUpperCase());
System.out.println(strOutput4.toUpperCase());
System.out.println(strOutput5.toUpperCase());
What about this:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the key consisting of 5 characters:");
String input = scanner.next();
//find positions of '0' in input
List<Integer> varPositions = findVarPositions(input);
//create permutations
List<String> permutations = new ArrayList<>();
permutations.add(input);//AB0C0
for (int position : varPositions) {
permutations = permutateAtPosition(permutations, position);
}
//print permutations
for (String permutation : permutations) {
System.out.println(permutation.toUpperCase());
}
}
private static List<Integer> findVarPositions(String input) {
List<Integer> varPositions = new ArrayList<>();
int lastVarPosition = -1;
while ((lastVarPosition = input.indexOf('0', lastVarPosition + 1)) != -1) {
varPositions.add(lastVarPosition);
}
return varPositions;
}
private static List<String> permutateAtPosition(List<String> partialyPermutated, int position) {
List<String> result = new ArrayList<>();
char[] replacements = {'1', '2', '3', '4', '5'};
for (String item : partialyPermutated) {
for (int i = 0; i < replacements.length; i++) {
String output = replaceCharAt(item, position, replacements[i]);
result.add(output);
}
}
return result;
}
private static String replaceCharAt(String input, int position, char replacement) {
//converting to char array, because there's no method like
//String.replaceAtPosition(position, char)
char[] charArray = input.toCharArray();
charArray[position] = replacement;
return new String(charArray);
}
}
It's not fixed to a number of variables.
The idea is to extract positions of '0' and subsequently call the method permutateAtPosition, which takes a partially permutated list and permutates it by one more level.
For "a0b0c0" and values 1-2 it would be ['a0b0c0'], then ['a1b0c0','a2b0c0'], then ['a1b1c0','a1b2c0','a2b1c0','a2b2c0'], and finally ['a1b1c1','a1b1c2','a1b2c1','a1b2c2','a2b1c1','a2b1c2','a2b2c1''a2b2c2'].
This solution keeps everything in memory, so in the general case (unlimited input string) it would be wiser to go with depth-first instead.
I've got another solution for you.
First step, getting the amount of variables:
int variableCount = 0;
for (int i = 0; i < 5; i++) {
if (input.charAt(i) == '0') {
variableCount++;
}
}
Then calculating the amount of results we are expecting:
int countMax = (int)Math.pow(4,variableCount);
Lastly, count up in base 4. Pad the number with 0's and replace the original input 0's:
for (int i = 0; i < countMax; i++) {
String paddedNumbers = format("%" + variableCount + "s",Integer.toString(i, 4)).replace(" ", "0");
int replacedCount = 0;
char[] outputChars = input.toCharArray();
for (int j = 0; j < 5; j++) {
if (input.charAt(j) == '0') {
outputChars[j] = paddedNumbers.charAt(replacedCount);
replacedCount++;
}
}
System.out.println(outputChars);
}

Maximum repeated String in an array

The problem is
how to get the maximum repeated String in an array using only operations on the arrays in java?
so i got into this question in a test and couldn't figure it out.
lets suppose we have an array of string.
str1[] = { "abbey", "bob", "caley", "caley", "zeeman", "abbey", "bob", "abbey" }
str2[] = { "abbey", "bob", "caley", "caley", "zeeman", "abbey", "bob", "abbey", "caley" }
in str1 abbey was maximum repeated, so abbey should be returned and
in str2 abbey and caley both have same number of repetitions and hence we take maximum alphabet as the winner and is returned(caley here).
c > a
so i tried till
import java.util.*;
public class test {
static String highestRepeated(String[] str) {
int n = str.length, num = 0;
String temp;
String str2[] = new String[n / 2];
for (int k = 0;k < n; k++) { // outer comparision
for (int l = k + 1; l < n; l++) { // inner comparision
if (str[k].equals(str[l])) {
// if matched, increase count
num++;
}
}
// I'm stuck here
}
return result;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("enter how many votes");
int n = sc.nextInt();
String[] str = new String[n];
for (int i = 0; i < n; i++) {
Str[i] = sc.nextLine();
}
String res = highestRepeated(str);
System.out.println(res + " is the winner");
}
}
so, how should i take the count of occurrence of each string with and attach it with the string itself.
All this, without using a map and any hashing but just by using arrays?
Here is a (unpolished) solution:
static String highestRepeated(String[] str) {
String[] sorted = Arrays.copyOf(str, str.length);
Arrays.sort(sorted, 0, sorted.length, Comparator.reverseOrder());
String currentString = sorted[0];
String bestString = sorted[0];
int maxCount = 1;
int currentCount = 1;
for (int i = 1 ; i < sorted.length ; i++) {
if (currentString.equals(sorted[i])) {
currentCount++;
} else {
if (maxCount < currentCount) {
maxCount = currentCount;
bestString = currentString;
}
currentString = sorted[i];
currentCount = 1;
}
}
if (currentCount > maxCount) {
return currentString;
}
return bestString;
}
Explanation:
Sort the array from highest to lowest lexicographically. That's what Arrays.sort(sorted, 0, sorted.length, Comparator.reverseOrder()); does. we sort in this order because you want the largest string if there are multiple strings with the same number of repeats.
Now we can just count the strings by looping through the array. We don't need a hash map or anything because we know that there will be no more of a string in the rest of the array when we encounter a different string.
currentString is the string that we are currently counting the number of repeats of, using currentCount. maxCount is the number of occurrence of the most repeated string - bestString - that we have currently counted.
The if statement is pretty self-explanatory: if it is the same string, count it, otherwise see if the previous string we counted (currentCount) appears more times than the current max.
At the end, I check if the last string being counted is more than max. If the last string in the array happens to be the most repeated one, bestString won't be assigned to it because bestString is only assigned when a different string is encountered.
Note that this algorithm does not handle edge cases like empty arrays or only one element arrays. I'm sure you will figure that out yourself.
another version
static String lastMostFrequent(String ... strs) {
if (strs.length == 0) return null;
Arrays.sort(strs);
String str = strs[0];
for (int longest=0, l=1, i=1; i<strs.length; i++) {
if (!strs[i-1].equals(strs[i])) { l=1; continue; }
if (++l < longest) continue;
longest = l;
str = strs[i];
}
return str;
}
change in
if (++l <= longest) continue;
for firstMostFrequent
you can't use == to check if two strings are the same.
try using this instead:
if (str[k].equals(str[l])) {
// if matched, increase count
num++;
}

Algorithm to generating all permutations of a string with no adjacent characters

Let's say I have ABCDEF. Then, there are 6! permutations of reordering that string. Now, I would like to only deal with the permutations in which there are no adjacent characters. That means, I want to look at all the permutations that satisfy these constraints:
B is not next to A or C
C is not next to B or D
D is not next to C or E
E is not next to D or F
My approach to this algorithm is the following pseudocode:
//generate all 6! permutations
//check all permutations and see where B is next to A || C
//remove all instances
//check all permutations and see where C is next to D
//remove all instances
//check all permutations and see where D is next to E
//remove all instances
//check all permutations and see where E is next to F
//remove all instances
However, these masking operations are becoming very inefficient and taking me much too long, especially if my string length is greater than 6. How can I do this more efficiently? I see these similar posts, 1, 2, and was hoping to extract some key ideas that might help me. However, this is also brute-force checking. I would like to actually generate only the unique patterns from the start and not have to generate everything and check one by one.
EDIT: Currently this is what I am using to generate all the permutations.
static String[] designs;
static int index;
protected static String[] generateDesigns(int lengthOfSequence, int numOfPermutations){
designs = new String[numOfPermutations];
StringBuilder str = new StringBuilder("1");
for(int i = 2; i <= lengthOfSequence; i++)
str.append(i);
genDesigns("", str.toString()); //genDesigns(6) = 123456 will be the unique characters
return designs;
}
//generate all permutations for lenOfSequence characters
protected static void genDesigns(String prefix, String data){
int n = data.length();
if (n == 0) designs[index++] = prefix;
else {
for (int i = 0; i < n; i++)
genDesigns(prefix + data.charAt(i), data.substring(0, i) + data.substring(i+1, n));
}
}
The typical O(n!) pseudo-code of algorithm to generate all permutations of a string of length n:
function permute(String s, int left, int right)
{
if (left == right)
print s
else
{
for (int i = left; i <= right; i++)
{
swap(s[left], s[i]);
permute(s, left + 1, right);
swap(s[left], s[i]); // backtrack
}
}
}
The corresponding recursion tree for string ABC looks like [image taken from internet]:
Just before swapping, check whether you can swap satisfying the given constraint (checking new previous and new next characters of both s[left] and s[i]). This will cut many branches off of the recursion tree too.
Here’s a fairly straightforward backtracking solution pruning the search before adding an adjacent character to the permutation.
public class PermutationsNoAdjacent {
private char[] inputChars;
private boolean[] inputUsed;
private char[] outputChars;
private List<String> permutations = new ArrayList<>();
public PermutationsNoAdjacent(String inputString) {
inputChars = inputString.toCharArray();
inputUsed = new boolean[inputString.length()];
outputChars = new char[inputString.length()];
}
private String[] generatePermutations() {
tryFirst();
return permutations.toArray(new String[permutations.size()]);
}
private void tryFirst() {
for (int inputIndex = 0; inputIndex < inputChars.length; inputIndex++) {
assert !inputUsed[inputIndex] : inputIndex;
outputChars[0] = inputChars[inputIndex];
inputUsed[inputIndex] = true;
tryNext(inputIndex, 1);
inputUsed[inputIndex] = false;
}
}
private void tryNext(int previousInputIndex, int outputIndex) {
if (outputIndex == outputChars.length) { // done
permutations.add(new String(outputChars));
} else {
// avoid previousInputIndex and adjecent indices
for (int inputIndex = 0; inputIndex < previousInputIndex - 1; inputIndex++) {
if (!inputUsed[inputIndex]) {
outputChars[outputIndex] = inputChars[inputIndex];
inputUsed[inputIndex] = true;
tryNext(inputIndex, outputIndex + 1);
inputUsed[inputIndex] = false;
}
}
for (int inputIndex = previousInputIndex + 2; inputIndex < inputChars.length; inputIndex++) {
if (!inputUsed[inputIndex]) {
outputChars[outputIndex] = inputChars[inputIndex];
inputUsed[inputIndex] = true;
tryNext(inputIndex, outputIndex + 1);
inputUsed[inputIndex] = false;
}
}
}
}
public static void main(String... args) {
String[] permutations = new PermutationsNoAdjacent("ABCDEF").generatePermutations();
for (String permutation : permutations) {
System.out.println(permutation);
}
}
}
It prints 90 permutations of ABCDEF. I’ll just quote the beginning and the end:
ACEBDF
ACEBFD
ACFDBE
ADBECF
…
FDBEAC
FDBECA

Random password generation

I have written a code for random password generation.There are a string from where i have to make the password.so i try to categorize the string according to uppercase array , lower case array and digit array. but here comes a problem when..
for(int k=0;k<Length;k++){
if(asc[k]>=65 && asc[k]<=90){
UpperCase[k]=(char)asc[k];
}
else if(asc[k]>=48 && asc[k]<=57){
Digit[k]=(char)asc[k];
}
else {
Mixed[k]=(char)asc[k];
}
}
is executed it counts some space which i don't want.coding looks like ugly sry for my poor coding.i know there is a lot more way to solve it but i want to go through this.here is my code. here is my code
import java.util.Random;
public class Randompassgeneration
{
final int MAX_LENGTH = 20;
final int MIN_LENGTH = 3;
char[] password=new char[25];
int [] asc=new int[18];
char[] UpperCase=new char[25];
char[] Digit=new char[25];
char[] Mixed=new char[25];
public void generate(String allowedCharacters)
{
int Length=allowedCharacters.length();
for (int i=0;i<Length;i++)
{
asc[i]=(int)allowedCharacters.charAt(i);
}
for (int k=0;k<Length;k++)
{
if (asc[k]>=65 && asc[k]<=90)
{
UpperCase[k]=(char)asc[k];
}
else if (asc[k]>=48 && asc[k]<=57)
{
Digit[k]=(char)asc[k];
}
else
{
Mixed[k]=(char)asc[k];
}
}
String rp=null;
StringBuilder Strbld=new StringBuilder();
Random rnd=new Random();
int ranStrLen=rnd.nextInt(MAX_LENGTH - MIN_LENGTH + 1) + MIN_LENGTH;
Strbld.append(UpperCase[rnd.nextInt(UpperCase.length)]);
Strbld.append(Digit[rnd.nextInt(Digit.length)]);
for (int m=0; m<ranStrLen-2; m++)
{
Strbld.append(Mixed[rnd.nextInt(Mixed.length)]);
}
System.out.print(ranStrLen +"->"+ Strbld.toString());
}
public static void main(String[] args)
{
String allowedCharacters = "weakPasSWorD1234$*";
Randompassgeneration t=new Randompassgeneration();
t.generate(allowedCharacters);
}
}
Any kind of suggestion?
I would generate the minimum number of characters, digits and symbols. Fill the other characters randomly and shuffle the result. This way it will comply with your minimum requirements with a minimum of effort.
public static String passwordGenerator() {
List<Character> chars = new ArrayList<>();
Random rand = new Random();
// min number of digits
for (int i = 0; i < 1; i++) chars.add((char) ('0' + rand.nextInt(10)));
// min number of lower case
for (int i = 0; i < 2; i++) chars.add((char) ('a' + rand.nextInt(26)));
// min number of upper case
for (int i = 0; i < 1; i++) chars.add((char) ('A' + rand.nextInt(26)));
// min number of symbols
String symbols = "!\"$%^&*()_+{}:#~<>?,./;'#][=-\\|'";
for (int i = 0; i < 1; i++) chars.add(symbols.charAt(rand.nextInt(symbols.length())));
// fill in the rest
while (chars.size() < 8) chars.add((char) ('!' + rand.nextInt(93)));
// appear in a random order
Collections.shuffle(chars);
// turn into a String
char[] arr = new char[chars.size()];
for (int i = 0; i < chars.size(); i++) arr[i] = chars.get(i);
return new String(arr);
}
public static void main(String... args) {
for (int i = 0; i < 100; i++)
System.out.println(passwordGenerator());
}
"is executed it counts some space which i don't want"
The white space is beacuse of your For loop
You were using the variable k for all the arrays,which resulted into the incremented value of k each time.So,this was making "gaps" between your arrays.
Change it to:
int point1=0,point2=0,point3=0;
for (int k=0;k<Length;k++)
{
if (asc[k]>=65 && asc[k]<=90)
{
UpperCase[point1]=(char)asc[k];point1++;
continue;
}
else if (asc[k]>=48 && asc[k]<=57)
{
Digit[point2]=(char)asc[k];point2++;
continue;
}
else
{
Mixed[point3]=(char)asc[k];point3++;
}
}
System.out.println(UpperCase);
System.out.println(Digit);
System.out.println(Mixed);
OutPut:
PSWD
1234
weakasor$*
Ok if not mistaken you want to parse the password generated and want put them in separate array. Here is the snippet for uppercase.
ArrayList<Character> uppercase = new ArrayList<Character>();
char pass[] = password.toCharArray();
for(char c: pass){
if(Character.isUpperCase(c))
uppercase.add(c);
}
If you want a random string, you could do:
public String getRandomString(){
return UUID.randomUUID().toString();
}
If you want to make it consistent with some source String, you could do:
public String getConsistentHash(String source){
return UUID.nameUUIDFromBytes(source.getBytes()).toString();
}
This latter method will return the same String for the same source String.
If there is a only a limited set of characters you want to use, you could just replace the unwanted chars. Suppose you have have created "randomString" as above, you create "randomString1" with:
randomString1 = UUID.fromString(randomString);
Now replace the unwanted chars in "randomString" with the chars in "randomString1". You could repeat this if necessary.
If you do not care for a minimum size/spread, you could just remove the chars.
Good luck.

Categories

Resources