Go: package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

var scanner = bufio.NewScanner(os.Stdin)

func main() {
	dictionary := make(map[string][]int)

	for {
		var word string
		var page int
		fmt.Scanf("%s %d", &word, &page)

		if word == "" || page == 0 {
			break
		}

		pages := dictionary[word]
		pages = append(pages, page)
		dictionary[word] = pages
	}

	words := make([]string, 0)
	for i := range dictionary {
		words = append(words, i)
	}

	sort.Strings(words)

	for _, v := range words {
		sort.Ints(dictionary[v])
		fmt.Println(v)
		for i, page := range dictionary[v] {
			if i == len(dictionary[v])-1 {
				fmt.Printf("%d\n", page)
			} else {
				fmt.Printf("%d ", page)
			}
		}
	}
}

C++: #include <stdio.h>
#include <string.h>

typedef int		BOOL;
#define TRUE	1;
#define FALSE	0;

typedef struct Word
{
	char	word[31];
	int		page;
}	WORD;

WORD wordArray[100];

void input();
	BOOL is_smaller(char *, int, int);
void output();

int main()
{
    input();
    output();
	
	return 0;
}

void input()
{
	int 	cnt1, cnt2;
	char	tempWord[31];
    int		tempPage;
	
	while(scanf("%s %d", tempWord, &tempPage) != EOF)
	{
		for(cnt1 = 0; cnt1 < 100; cnt1++)
		{
			if(wordArray[cnt1].page == 0)
			{
				wordArray[cnt1].page = tempPage;
				strcpy(wordArray[cnt1].word, tempWord);
				break;
			}
			else if(is_smaller(tempWord, tempPage, cnt1))
			{
				for(cnt2 = 98; cnt2 >= cnt1; cnt2--)
				{
					strcpy(wordArray[cnt2 + 1].word, wordArray[cnt2].word);
					wordArray[cnt2 + 1].page = wordArray[cnt2].page;
				}
				strcpy(wordArray[cnt1].word, tempWord);
				wordArray[cnt1].page = tempPage;
				break;
			}
		}
	}
}

BOOL is_smaller(char *tempWord, int input_page, int cnt)
{
	if(strcmp(tempWord, wordArray[cnt].word) < 0)
	{
		return TRUE;
	}
	else if(strcmp(tempWord, wordArray[cnt].word) == 0)
	{
		if(input_page < wordArray[cnt].page)
		{
			return TRUE;
		}
		else
		{
			return FALSE;
		}
	}
	else
	{
		return FALSE;
	}
}

void output()
{
	int		output_cnt = 0;
	char	last_print_word[31] = "";

	while(wordArray[output_cnt].page != 0)
	{
		if(strcmp(last_print_word, "") == 0)
		{
			printf("%s\n", wordArray[output_cnt].word);
			strcpy(last_print_word, wordArray[output_cnt].word);
		}
		else if(strcmp(wordArray[output_cnt].word, last_print_word) != 0)
		{
			printf("\n%s\n", wordArray[output_cnt].word);
			strcpy(last_print_word, wordArray[output_cnt].word);
		}
		else
		{
			printf(" ");
			
		}
		printf("%d", wordArray[output_cnt].page);
		output_cnt++;
	}
	printf("\n");
}

C++: #include<iostream>
#include<string.h>
#include<vector>
#include<list>
#include<stdio.h>
#include<math.h>
#include<iomanip>
#include<map>
#include<stack>
#include<queue>
#include<algorithm>
#define range(i,a,b) for(int i = (a); i < (b); i++)
#define rep(i,b) range(i,0,b)
#define debug(x) cout << "debug " << x << endl;
using namespace std;

struct Book{
    string s;
    vector<int> page;
};

int main(){
    string s;
    int p, i = 0;
    struct Book book[105];
    while(cin >> s >> p){
        bool c = true;
        rep(j,i){
            if(book[j].s == s){
                book[j].page.push_back(p);
                c = false;
            }
        }
        if(c){
            book[i].s = s;
            book[i].page.push_back(p);
            i++;
        }
    }
    rep(j,i + 1){
        for(int k = i; k >= j; k--){
            if(book[k].s < book[k - 1].s){
                struct Book g = book[k];
                book[k] = book[k - 1];
                book[k - 1] = g;
            }
        }
    }
    rep(j,i + 1){
        debug(book[j].s)
        sort(book[j].page.begin(), book[j].page.end());
    }
    range(j, 1, i + 1){
        cout << book[j].s << endl;
        rep(k, book[j].page.size()){
            if(k) cout << ' ';
            cout << book[j].page[k];
        }
        cout << endl;
    }
}

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

using namespace std;

struct BooKIndex{
  vector<int> page;
  string word;
  BooKIndex(const int &p,const string &w){
    word=w;
    page.push_back(p);
  }
  bool operator==(const BooKIndex &b)const{
    return word==b.word;
  }
  bool operator<(const BooKIndex &b)const{
    return word<b.word;
  }
};

int main(){
  vector<BooKIndex> indexlist;
  string word;
  int page;
  while(cin>>word>>page){
    auto idx=find(indexlist.begin(),indexlist.end(),BooKIndex(page,word));
    if(idx!=indexlist.cend())
      idx->page.push_back(page);
    else
      indexlist.push_back(BooKIndex(page,word));
  }
  for(auto &l:indexlist){
    sort(l.page.begin(),l.page.end());
  }
  sort(indexlist.begin(),indexlist.end());
  for(auto l:indexlist){
    cout<<l.word<<endl;
    for(int i=0;i<l.page.size();i++)
      cout<<l.page[i]<<((i!=l.page.size()-1)?' ':'\n');
  }

}

C++: #include<functional>
#include<list>
#include<queue>
#include<stack>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>


class word{
 public:
  char w[31];
  std::priority_queue<int> q;
};


int main(){
  using namespace std;  
  int p,cmp;
  char str[31];
  list<word> wlst;
  list<word>::iterator it;
  stack<int> b;
  word *buf;

  while(scanf("%s %d",str,&p)!=EOF){
    it=wlst.begin();
    while(it!=wlst.end()){
      cmp=strcmp(it->w,str);
      if(!cmp){
	it->q.push(p);
	break;
      }else if(cmp>0){
	buf=new word();
	strcpy(buf->w,str);
	buf->q.push(p);
	wlst.insert(it,*buf);
	break;
      }
      ++it;
    }
    if(it==wlst.end()){
      buf=new word();
      strcpy(buf->w,str);
      buf->q.push(p);
      wlst.insert(it,*buf);
    }
  }
  it=wlst.begin();
  while(it!=wlst.end()){
    printf("%s\n",it->w);
    while(!(it->q.empty())){
      b.push(it->q.top());
      it->q.pop();
    }
    while(1){
      printf("%d",b.top());
      b.pop();
      if(b.empty()){
	printf("\n");
	break;
      }else{
	printf(" ");
      }
    }
    it++;
  }
  return 0;
}

C++: /* -- 0105:Book Index -- */

#include	<iostream>
#include	<string>
#include	<vector>
#include	<utility>
#include	<algorithm>

using namespace std;

typedef pair< string, int > P;
typedef vector< P > Vec_S_I;

int main(void) {
	Vec_S_I Indexes;
	int buf_i, c;
	string buf_s;
	bool mstFirst = true, i_First = true;
	
	while(1) {
		cin >> buf_s >> buf_i;
		
		if( cin.eof() ) { break; }
		Indexes.push_back(P(buf_s, buf_i));
	}
	sort(Indexes.begin(), Indexes.end());
	Vec_S_I::iterator it = Indexes.begin();
	buf_s.erase();
	while(it != Indexes.end()) {
		if(buf_s != it->first) {
			if(!mstFirst) { cout << endl; }
			cout << it->first << endl;
			buf_s = it->first;
			i_First = true;
		}
		if(!i_First) { cout << ' '; }
		cout << it->second;
		i_First = false;
		mstFirst = false;
		it++;
	}
	return 0;
}