G
G
goalrazor2020-08-16 18:02:49
Java
goalrazor, 2020-08-16 18:02:49

There is a task in JAVA - no answer. How to solve the problem?

They gave me a test task. It is checked automatically on closed test data, but I always get the answer "wrong solution". That is, apparently did not take into account some case that may exist. Tell me the solution, or at least the case that I did not take into account.

Task condition

Time limit, s 1
Memory limit, MB 64
Total number of sending attempts 15

2 lines are fed as input. It is necessary to determine whether it is possible to turn the first line into the second, replacing one letter with another, taking into account the following rules:

- only the letters of the Russian alphabet а-z are involved;
- all letters in lower case;
- in one step, you can convert all occurrences of one letter to another.

Input data
The input information comes from the standard input as a single line. This string contains two substrings separated by a space. Your decision should take into account the variant when strings of different lengths are given as input. Incorrect input data is not received, additional checks are not required.

Output
As a response to the standard output, the program should output 1 (if it can be converted) or 0 (if it can't be converted).

Example 1
Input: hello fun
Output: 1
Transformation (no need to output):
to ⇒ k (prick)
e ⇒ o (prick)
t ⇒ l (fun)

Example 2
Input: aabddd ddbbaa
Output: 1
Transform (output not necessary):
d ⇒ i (aabbya) a
⇒ d (ddbbya) i
⇒ a ( ddbbaa

)

import java.io.IOException;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) throws IOException {
        Scanner scanner = new Scanner(System.in);
        String twoLines = scanner.nextLine();
        System.out.println(isEqual(twoLines));
    }
  
 public static String getFreeSymbol(String first, String second) {
        int symbolInt = 'а';
        while (first.contains(String.valueOf((char) symbolInt)) || second.contains(String.valueOf((char) symbolInt))) {
            symbolInt++;
        }
        return String.valueOf((char) symbolInt);
    }

    public static int isEqual(String targetString) {
        targetString = targetString.toLowerCase();
        String[] lines = targetString.split(" ", 2);

        String firstString = lines[0];
        String secondString = lines[1];
        if (firstString.length() != secondString.length()) {
            return 0;
        }
        return isEqual(firstString, secondString);
    }

    public static String check(String firstString, String secondString, String findSymbol, String replaceSymbol, int index, int secondIndex, int i) {
        if ((secondIndex = secondString.indexOf(findSymbol, secondIndex + 1)) > -1) {
            if (firstString.charAt(secondIndex) != secondString.charAt(secondIndex)) {
                if (firstString.charAt(index) == firstString.charAt(secondIndex)) {
                    String freeSymbol = getFreeSymbol(firstString, secondString);
                    firstString = firstString.replaceAll(replaceSymbol, freeSymbol);
                    findSymbol = firstString.substring(i, i + 1);
                } else {
                    if (firstString.charAt(index) == secondString.charAt(index)) {
                        return null;
                    } else {
                        String freeSymbol = getFreeSymbol(firstString, secondString);
                        firstString = firstString.replaceAll(replaceSymbol, freeSymbol);
                    }
                }
            }
        }else{
            findSymbol = secondString.substring(index, index+1);
            String anchorSymbol = firstString.substring(index, index+1);

            do {
                String symbol = firstString.substring(index, index+1);
                if( !symbol.equals(anchorSymbol) ){
                    return null;
                }
                index++;
            } while ((index = secondString.indexOf(findSymbol, index)) > -1);

        }
        return firstString;
    }

    public static int isEqual(String firstString, String secondString) {

        boolean[] isCheck = new boolean[firstString.length()];
        for (int i = 0; i < isCheck.length; i++) {
            String findSymbol = firstString.substring(i, i + 1);
            String replaceSymbol = secondString.substring(i, i + 1);

            if (isCheck[i]) {
                continue;
            }
            int index = i;
            int secondIndex = i;
            String rez = check(firstString, secondString, findSymbol, replaceSymbol, index, secondIndex, i);
            if (rez == null) {
                return 0;
            }else{
                firstString = rez;
            }

            do {
                firstString = firstString.replaceFirst(findSymbol, replaceSymbol);
                isCheck[index] = true;
                index++;
            } while ((index = firstString.indexOf(findSymbol, index)) > -1);
        }
        String result = firstString;
        if (result.equals(secondString)) {
            return 1;
        } else {
            return 0;
        }
    }

  
}

Answer the question

In order to leave comments, you need to log in

2 answer(s)
W
Wataru, 2020-08-16
@wataru

You have a lot of tricks - a lot where you can make a mistake. You use some indexOf() a bunch of times, although you can simply compare characters through CharAt(), substrings are everywhere. I advise you to rewrite your solution from scratch, it is impossible to look for errors in it.
In the problem, we need to consider an important case when all the letters of the alphabet are occupied, in this case, if the lines are not the same, then the answer is 0. It looks like your solution will use a character outside the alphabet.
You only need to check that the characters in the same places are the same or different in both lines. Well, or equivalently - that for each character the previous one is the same in both lines at the same distance. The easiest way is to get 2 map from character to position. Go through two lines in parallel and make sure that the previous occurrences of these characters in the lines are in the same position (or not) and update the entries in the map.
Something like this (read as pseudocode, I don't really know Java):

public static int isEqual(String firstString, String secondString) {
  int used = 0;
  int[] first = new int[256], second = new int[256];
  if (firstString == secondString) return 1;
  if (firstString.length() != secondString.length()) return 0;
  for (i = 0; i < firstString.lengt(); ++i) {
    int ch1 = Character.getNumericValue(firstString.charAt(i));
    int ch2 = Character.getNumericValue(secondString.charAt(i));
    if (first[ch1] == 0) {
      used++;
    }
    if (first[ch1] != second[ch2]) return 0;
    first[ch1] = i+1;  // +1, потому что изначальные 0 означают "символ не встречался"
    second[ch2] = i+1; 
  }
  if (used == 33) return 0;
  return 1;

Perhaps it is better to rewrite with Map, I don’t know what will happen with the encodings, maybe the characters are not single-byte and 256 in the tables is not enough.

S
Sergey_USB, 2020-08-16
@Sergey_USB

They gave me a test task, I solved it, but why is it wrong?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question