いろんな言語で配列(リスト・ベクトル)の逆順を出す

ふるいにかけるべく「int型の配列を引数として要素の順番を逆転する関数を作って下さい。言語は何でも構いません」という問題を出したことが。長い業務経験を持ちながら出来ないプログラマが意外にいる事実に衝撃を受けました。世間は広い…
Oct 10 via EchofonFavoriteRetweetReply

に刺激を受けていろいろな言語で配列(or list or vector)の逆順を作成。。。
やはりC++がおまじない含めると一番めんどい。

  • C++
    • STLのreverse使った版
#include <iostream>
#include <algorithm>
#include <vector>

//Generate functor
class Generator
{
	int x;
public : 
	Generator() : x(0){}
	int operator() (){return x++;}
};
//show argument 
void Show(int x)
{
	std::cout << " " << x;
}
//main
int main()
{
	//create vector object
	std::vector<int> x(5);
	std::generate(x.begin(), x.end(), Generator());

	//show original
	std::for_each(x.begin(), x.end(), Show);
	std::cout << std::endl;
	
	//create & show inverse
	std::reverse(x.begin(), x.end());
	std::for_each(x.begin(), x.end(), Show);
	std::cout << std::endl;

	return 0;
}
    • 自分で逆順にする関数書いた版
#include <iostream>
#include <algorithm>
#include <vector>

//Generate functor
class Generator
{
	int x;
public : 
	Generator() : x(0){}
	int operator() (){return x++;}
};
//show argument 
void Show(int x)
{
	std::cout << " " << x;
}
//My Reverse Func
std::vector<int> MyReverse(const std::vector<int> & x)
{
	std::vector<int> result(x.size());
	
	std::vector<int>::const_reverse_iterator it1 = x.rbegin();
	std::vector<int>::iterator it2 = result.begin();
	for(; it1 != x.rend(); it2++, it1++)
	{
		*it2 = *it1;
	}

	return result;
}
//main
int main()
{
	//create vector object
	std::vector<int> x(5);
	std::generate(x.begin(), x.end(), Generator());

	//show original
	std::for_each(x.begin(), x.end(), Show);
	std::cout << std::endl;
	
	//create & show inverse
	std::vector<int> y = MyReverse(x);
	std::for_each(y.begin(), y.end(), Show);
	std::cout << std::endl;

	return 0;
}

両方とも出力結果は

 0 1 2 3 4
 4 3 2 1 0
続行するには何かキーを押してください . . .
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static int[] MyReverse(int[] x)
        {
            int len = x.Length;
            int[] result = new int[len];
            for(int i = 0; i < len; i++)
            {
                result[i] = x[len - 1 - i];
            }
            return result;
        }
        static void Main(string[] args)
        {        
            int [] x = new []{1,2,3,4,5};
            for (int i = 0; i < x.Length; i++)
            {
                Console.Write(" {0}", x[i]);
            }
            Console.WriteLine("");


            int[] z = MyReverse(x);
            for (int i = 0; i < z.Length; i++)
            {
                Console.Write(" {0}", z[i]);
            }
            
        }
    }
}

結果

 1 2 3 4 5
 5 4 3 2 1続行するには何かキーを押してください . . .
  • F#
let x = [1..5]
let y = x |> List.rev
printfn "%A" y

printfnの結果

[5; 4; 3; 2; 1]
val it : unit = ()

これだけだとさみしいので自分実装版

let x = [1..10];;
//普通の再帰版
let rec myrev = function
    | head::tail -> myrev tail@[head] 
    | [] -> []
;;
//末尾再帰版
let rec myrev_tailrec list =
    let rec myrev_inner x accum = 
        match x with
        | head::tail -> myrev_inner tail (head::accum)
        | [] -> accum
    in myrev_inner list []
;;
//実行
myrev x;;
myrev_tailrec x;;

結果はちゃんと逆順になってる。

> val it : int list = [10; 9; 8; 7; 6; 5; 4; 3; 2; 1]
> val it : int list = [10; 9; 8; 7; 6; 5; 4; 3; 2; 1]
x = range(5)
print x
list.reverse(x)
print x

printの結果

[0, 1, 2, 3, 4]
[4, 3, 2, 1, 0]
  • R
x <- 1:5
rev(x)

revの結果

[1] 5 4 3 2 1