Task: Longest common prefix

C: #include<stdarg.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>

char* lcp(int num,...){
	va_list vaList,vaList2;
	int i,j,len,min;
	char* dest;
	char** strings = (char**)malloc(num*sizeof(char*));
	
	va_start(vaList,num);
	va_start(vaList2,num);
	
	for(i=0;i<num;i++){
		len = strlen(va_arg(vaList,char*));
		strings[i] = (char*)malloc((len + 1)*sizeof(char));
		
		strcpy(strings[i],va_arg(vaList2,char*));
		
		if(i==0)
			min = len;
		else if(len<min)
			min = len;
	}
	
	if(min==0)
		return "";
	
	for(i=0;i<min;i++){
		for(j=1;j<num;j++){
			if(strings[j][i]!=strings[0][i]){
				if(i==0)
					return "";
				else{
					dest = (char*)malloc(i*sizeof(char));
					strncpy(dest,strings[0],i-1);
					return dest;
				}
			}
		}
	}
	
	dest = (char*)malloc((min+1)*sizeof(char));
	strncpy(dest,strings[0],min);
	return dest;
}

int main(){

	printf("\nLongest common prefix : %s",lcp(3,"interspecies","interstellar","interstate"));
        printf("\nLongest common prefix : %s",lcp(2,"throne","throne"));
        printf("\nLongest common prefix : %s",lcp(2,"throne","dungeon"));
        printf("\nLongest common prefix : %s",lcp(3,"throne","","throne"));
        printf("\nLongest common prefix : %s",lcp(1,"cheese"));
        printf("\nLongest common prefix : %s",lcp(1,""));
        printf("\nLongest common prefix : %s",lcp(0,NULL));
        printf("\nLongest common prefix : %s",lcp(2,"prefix","suffix"));
        printf("\nLongest common prefix : %s",lcp(2,"foo","foobar"));
	return 0;
}


C++: #include <set>
#include <algorithm>
#include <string>
#include <iostream>
#include <vector>
#include <numeric>

std::set<std::string> createPrefixes ( const std::string & s ) {
   std::set<std::string> result ;
   for ( int i = 1 ; i < s.size( ) + 1 ; i++ )
      result.insert( s.substr( 0 , i )) ;
   return result ;
}

std::set<std::string> findIntersection ( const std::set<std::string> & a ,
      const std::set<std::string> & b ) {
   std::set<std::string> intersection ;
   std::set_intersection( a.begin( ) , a.end( ) , b.begin( ) , b.end( ) ,
	 std::inserter ( intersection , intersection.begin( ) ) ) ;
   return intersection  ;
}

std::set<std::string> findCommonPrefixes( const std::vector<std::string> & theStrings ) {
   std::set<std::string> result ;
   if ( theStrings.size( ) == 1 ) {
      result.insert( *(theStrings.begin( ) ) ) ;
   }
   if ( theStrings.size( ) > 1 ) {
      std::vector<std::set<std::string>> prefixCollector ;
      for ( std::string s : theStrings )
	 prefixCollector.push_back( createPrefixes ( s ) ) ;
      std::set<std::string> neutralElement (createPrefixes( *(theStrings.begin( ) ) )) ;
      result = std::accumulate( prefixCollector.begin( ) , prefixCollector.end( ) ,
	    neutralElement , findIntersection ) ;
   }
   return result ;
}

std::string lcp( const std::vector<std::string> & allStrings ) {
   if ( allStrings.size( ) == 0 ) 
      return "" ;
   if ( allStrings.size( ) == 1 ) {
      return allStrings[ 0 ] ;
   }
   if ( allStrings.size( ) > 1 ) {
      std::set<std::string> prefixes( findCommonPrefixes ( allStrings ) ) ;
      if ( prefixes.empty( ) ) 
	 return "" ;
      else {
	 std::vector<std::string> common ( prefixes.begin( ) , prefixes.end( ) ) ;
	 std::sort( common.begin( ) , common.end( ) , [] ( const std::string & a, 
		  const std::string & b ) { return a.length( ) > b.length( ) ; } ) ;
	 return *(common.begin( ) ) ;
      }
   }
}

int main( ) {
   std::vector<std::string> input { "interspecies" , "interstellar" , "interstate" } ;
   std::cout << "lcp(\"interspecies\",\"interstellar\",\"interstate\") = " << lcp ( input ) << std::endl ;
   input.clear( ) ;
   input.push_back( "throne" ) ;
   input.push_back ( "throne" ) ;
   std::cout << "lcp( \"throne\" , \"throne\"" << ") = " << lcp ( input ) << std::endl ;
   input.clear( ) ;
   input.push_back( "cheese" ) ;
   std::cout << "lcp( \"cheese\" ) = " << lcp ( input ) << std::endl ;
   input.clear( ) ;
   std::cout << "lcp(\"\") = " << lcp ( input ) << std::endl ;
   input.push_back( "prefix" ) ;
   input.push_back( "suffix" ) ;
   std::cout << "lcp( \"prefix\" , \"suffix\" ) = " << lcp ( input ) << std::endl ;
   input.clear( ) ;
   input.push_back( "foo" ) ;
   input.push_back( "foobar" ) ;
   std::cout << "lcp( \"foo\" , \"foobar\" ) = " << lcp ( input ) << std::endl ;
   return 0 ;
}