0

How to Concatenate the given n strings to make a single string such that on combining two strings the last character of first string should be same as the first character of next string.

For example:

Input: ab2c,h23f2,c4dsh

Output: ab2cc4dshh23f2

I tried using hashmap is there any better solution? I cannot be able to handle some cases like

Input: ab2c,h23fc,c555ab,c4dsh,

Output: ab2cc4dshh23fcc555ab

In the above example there are 2 possibilities for 2nd string but taking c555ab will lead to end of string. If there are many possibilities at different levels how to handle them so as to get the correct ans?

Community
  • 1
  • 1
Abhishek N
  • 57
  • 1
  • 8
  • 1
    This is less of a string concatenation issue and more of a logic problem, depending on the language in use there are several methods to try and solve the problem here using a substring function to compare the first to last characters and create output based on a match but the issue is around the determination of what is considered a 'right' solution. – Payload Sep 17 '16 at 09:33
  • Sounds like a perfect example of recursion. That way you can backtrack and choose a different path. Did you have a particular language in mind? – Jerry Jeremiah Sep 17 '16 at 09:33
  • No I just need algorithm. Any language is fine. – Abhishek N Sep 17 '16 at 10:10

2 Answers2

2

This is a simple Euler Path problem.

  1. Draw a directed graph with (26+10) nodes, each node corresponds to a lowercase English alphabet (a-z) and the 10 digits (0-9).
  2. For the ith given string draw an edge directed from the the first character to the last character of the string. Eg. For string abcd - draw an edge from node a to node d.
  3. Find a euler path in this graph. A euler path is a path which visits each and every edge of the graph once.

Understand that moving from an edge a-b to b-c in the euler path implies connecting two strings together with common alphabet as b and opposite end characters as a and c.

Correctness of the method -

A euler path will visit every edge exactly once meaning that every string is used once and concatenated in the order the path visits the nodes.

Make sure the euler path exists and then only try out the euler path algorithm.

Smooth_ops
  • 36
  • 3
0

Assuming the function is called concat and takes an array of strings pool as a first parameter, and an accumulator* string s as a second parameter:

Each time you enter the concat function, you can check the following rules:

  1. If pool is empty, then return s as it is a correct answer.
  2. If s does not have an acceptable match in pool, then backtrack by returning null or some indicator that there is no suitable answer for the inputs.
  3. Recurse on every acceptable match until either: there are no matches left, or, a correct answer is found.

This will ultimately lead to either a correct answer, or, to null or some other indicator value that the inputs had no answer.

*An accumulator string is one that accumulates a value between recursive function calls. In this case, it would start as an empty string in the initial call, and then at each invocation of concat deeper into the call stack, it would be concatenated by its match from pool.

Here is a small javascript implementation, if you run it it will produce a somewhat verbose log:

function concat(pool, s) {
 s = s === undefined ? '' : s;
 if (pool.length === 0) {
  log("empty pool, s: " + s);
  return s;
 }
 for (let itr = 0; itr < pool.length; ++itr) {
  let v = pool[itr];
  if (s.length === 0 || v.charAt(0) === s.charAt(s.length - 1)) {
   log(s + v + " is a candidate path, searching...");
   let ret = concat(nSlice(pool, itr), s + v);
   if (ret !== null) {
    log("returning non-null ret: " + ret);
    return ret;
   }
   log(s + v + " hit a dead end, continuing...");
  } else {
   log(s + v + " was not a candidate path, continuing...");
  }
 }
 log("Returning null for given s: " + s);
 return null;
}

function nSlice(arr, index) {
 let a = arr.slice(0);
 a.splice(index, 1);
 return a;
}

function log(m) {
    console.log(m);
    let e = document.createElement('div');
    e.innerHTML = m;
    document.body.appendChild(e);
}

[
 ['ab2c', 'h23f2', 'c4dsh'],
 ['ab2c', 'h23fc', 'c555ab', 'c4dsh'],
 ['h23fc', 'c555ab', 'c4dsh', 'ab2c']
].forEach(v => {
 concat(v);
 log("------------------");
});
jconder
  • 686
  • 4
  • 9