Проверить, является ли строка перетасовкой двух других заданных строк

Это вопрос из Руководства по проектированию алгоритмов:

Предположим, вам даны три строки символов: X, Y и Z, где |X| = n, |Y| = m и |Z| = n+m. Z считается перетасовкой X и Y тогда и только тогда, когда Z может быть сформирован путем чередования символов из X и Y. таким образом, чтобы поддерживать порядок символов слева направо в каждой строке.

Предложите эффективный алгоритм динамического программирования, который определяет, является ли Z перетасовкой X и Y.

Подсказка: значения создаваемой вами матрицы динамического программирования должны быть логическими, а не числовыми.

Вот что я пробовал:

Первоначально я создал массив одномерных символов и указатели на начальные символы X, Y, Z соответственно. Если Z-указатель совпадает с X-указателем, сохраните X в массиве символов, иначе проверьте то же самое с Y-указателем. Если каждая запись в массиве символов не отличается от ее последней записи, Z не чередуется.

Может ли кто-нибудь помочь мне с этой проблемой?


person piyukr    schedule 24.11.2013    source источник
comment
Пожалуйста, покажите, что вы пробовали.   -  person Abhishek Bansal    schedule 24.11.2013
comment
@Mörre Нет, это не моя домашняя работа. Я только процитировал Руководство по разработке алгоритмов.   -  person piyukr    schedule 24.11.2013
comment
Вам придется приложить некоторые усилия, если вы хотите получить хороший ответ от SO.   -  person Abhishek Bansal    schedule 24.11.2013
comment
@AbhishekBansal. Вот что я пробовал: сначала я создал массив одномерных символов и указатели на начальные символы X, Y, Z соответственно. Если Z-указатель совпадает с X-указателем, сохраните X в массиве символов, иначе проверьте то же самое с Y-указателем. Если каждая запись в массиве символов не отличается от ее последней записи, Z не чередуется.   -  person piyukr    schedule 24.11.2013


Ответы (5)


Следующий подход должен дать вам представление.

Определите условие d(s1,s2,s3) = (s1 + s2 == s3) { s3 is a shuffle of s1 and s2 }

Мы должны найти d( X, Y, Z ).

если длины s1 и s2 равны 1 каждая, а длина s3 = 2,

d( s1,s2,s3 ) = { (s1[0] == s3[0] && s2[0] == s3[1]) || (s1[0] == s3[1] && s2[0] == s3[0])

Аналогично можно получить d для пустых строк.

Для строк произвольной длины выполняется следующее соотношение.

d( s1,s2,s3 ) = { ( d( s1-s1[last],s2,s3 - s3[last]) && s1[last] == s3[last] )
                  || ( d( s1,s2 - s2[last],s3 - s3[last]) && s2[last] == s3[last] )
                }

Вы можете вычислить d() записей, начиная со строк нулевой длины, и продолжать проверку.

person Abhishek Bansal    schedule 24.11.2013
comment
разве чередование не означает, что последовательные символы в Z должны быть попеременно из X и Y? - person piyukr; 24.11.2013
comment
Нет. Чередование подразумевает только то, что Z должен содержать все символы X и Y и в том же порядке, что и в соответствующих строках. Например, abc и def и чередуются, чтобы сформировать abcdef. - person Abhishek Bansal; 24.11.2013

Во-первых, давайте начнем с некоторых определений. Я пишу X[i] для i элемента X и X[i) для подстроки X, начиная с индекса i.

Например, если X = abcde, то X[2] = c и X[2) = cde.

Аналогичные определения справедливы для Y и Z.


Чтобы решить проблему с помощью динамического программирования, вы должны сохранить двумерный логический массив A размера (n+1) x (m+1). В этом массиве A[i, j] = true тогда и только тогда, когда X[i) и Y[j) можно чередовать, чтобы сформировать Z[i+j).

Для произвольного (i, j) где-то в середине 2D-массива рекуррентное соотношение очень простое:

A[i, j] := X[i] = Z[i+j] and A[i+1, j]
        or Y[j] = Z[i+j] and A[i, j+1]

На краях 2D-массива у вас есть случай, когда либо X, либо Y уже находятся в его конце, что означает, что суффикс другого должен быть равен суффиксу Z:

A[m, j] := Y[j) = Z[m+j)
A[i, n] := X[i) = Z[i+n)
A[m, n] := true

Если вы сначала заполните границу массива (A[m, j] и A[i, n], для всех i, j), вы можете просто вернуться к A[0, 0] и установить записи соответствующим образом. В конце концов, A[0, 0] — ваш ответ.

person Vincent van der Weele    schedule 24.11.2013

Он определяется следующим рекуррентным соотношением: -

S(i,j,k) = false

if(Z(i)==Y(k))
  S(i,j,k) = S(i,j,k)||S(i+1,j,k+1)

if(Z(i)==X(j))
  S(i,j,k) = S(i,j,k)||S(i+1,j+1,k)

Where S(i,j,k) corresponds to Z[i to end] formed by shuffle of X[j to end] and Y[K to end]

Вы должны попытаться закодировать это в DP самостоятельно.

person Vikram Bhat    schedule 24.11.2013

РЕШЕНИЕ НА ОСНОВЕ JAVASCRIPT

 const first = "bac";
 const second = "def"
 const third = "dabecf";

function createDict(seq,str){
   let strObj = {};
   str = str.split("");
   str.forEach((letter,index)=>{
   strObj[letter] = {
       wordSeq: seq,
       index : index

   } ;
   })
   return strObj;
 }

function checkShuffleValidity(thirdWord,firstWord,secondWord){
    let firstWordDict = createDict('first',firstWord);
    let secondWordDict = createDict('second',secondWord);
    let wordDict = {...firstWordDict,...secondWordDict};
    let firstCount=0,secondCount = 0;
    thirdWord = thirdWord.split("");
    for(let i=0; i<thirdWord.length; i++){
        let letter = thirdWord[i];
         if(wordDict[letter].wordSeq == "first"){
      if(wordDict[letter].index === firstCount){
         firstCount++;
      }else{
        return false
      }        
    }else{
    if(wordDict[letter].index === secondCount){
      secondCount++;
    }else{
      return false;
    }

    }
}  
return true;
}

 console.log(checkShuffleValidity(third,first,second));
person srujan chakravarthy    schedule 13.01.2020

Ключевые моменты:

  1. Все строки не должны быть нулевыми или пустыми.
  2. Сумма длин двух строк должна быть равна длине третьей строки.
  3. Третья строка не должна содержать подстроки двух строк.
  4. В противном случае создайте массивы символов, отсортируйте и сравните.

Код:

public static boolean validShuffle(String first, String second, String third){
  boolean status=false;
  if((first==null || second==null || third==null) || (first.isEmpty()|| second.isEmpty() || third.isEmpty())){
    status = false;
  } else if((first.length()+second.length()) !=third.length()){
    //check if the sum of 2 lengths equals to the third string length
    status = false;
  } else if(third.indexOf(first,0)!=-1 || third.indexOf(second,0)!=-1){
    //check if the third string contains substrings
    status = false;
  } else {
    char [] c1_2=(first+second).toCharArray();
    char [] c3 =third.toCharArray();
    Arrays.sort(c1_2);
    Arrays.sort(c3);
    status=Arrays.equals(c1_2, c3);
  }
  return status;
}
person siyabonga mdletshe    schedule 17.06.2016