• 【C++】随机重命名MP3文件


    新置MP3一件。竟然没有随机播放的功能,坑啊!

    身为程序媛一枚,自己动手吧~

    获取当前路径:

    char buf[1000];
    	GetCurrentDirectory(1000,buf); 
    	string cur_folder_file = string(buf)+"\*.mp3";
    获取当前路径mp3文件列表:

    void getMp3Names(string filepath,vector<string> &names)
    {
    	names.clear();
    	WIN32_FIND_DATA f;
    	HANDLE h = FindFirstFile(filepath.c_str() , &f);
    	if(h != INVALID_HANDLE_VALUE)
    	{
    		do
    		{
    			names.push_back(f.cFileName);
    		} while(FindNextFile(h, &f));
    	}
    	FindClose(h);	
    }
    随机重命名mp3文件(命名为num.mp3,如5.mp3):

    void renameMp3Names(vector<string> &names){
    	int mp3_num = names.size();
    	vector<bool> used_names(mp3_num,false);
    	srand(time(NULL));  
    	for(int i=0;i<mp3_num;i++){
    		int new_name_num = -1;
    		while(new_name_num<0){
    			int tmp= rand()%mp3_num;
    			if(!used_names[tmp]){
    				new_name_num = tmp;
    				used_names[tmp] = true;
    			}
    		}
    		char char_tmp[100];
    		itoa(new_name_num,char_tmp,10);
    		string new_name = string(char_tmp)+".mp3";
    		if(!_access(names[i].c_str(),0))
    		{
    			if(!rename(names[i].c_str(),new_name.c_str()))
    			{
    				cout<<"RENAME "<<names[i]<<" AS: "<<new_name<<""<<endl;
    			}
    		}
    	}
    	return ;
    }

    基本能够啦~


    只是有一点,这个程序执行第二遍就有问题了,由于全部的文件都变成了 num.mp3。再次随机重命名的时候就会出现冲突,重名文件存在导致rename()失败!

    再小小改动一下:

    void renameMp3Names(vector<string> &names){
    	cout<<"---------------RENAME MP3 FILES---------------"<<endl;
    	int mp3_num = names.size();
    	vector<bool> used_names(mp3_num,false);
    	srand(time(NULL));  
    	for(int i=0;i<mp3_num;i++){
    		int new_name_num = -1;
    		while(new_name_num<0){
    			int tmp= rand()%mp3_num;
    			if(!used_names[tmp]){
    				new_name_num = tmp;
    				used_names[tmp] = true;
    			}
    		}
    		char char_tmp[100];
    		itoa(new_name_num,char_tmp,10);
    		string new_name = string("tmp")+string(char_tmp)+".mp3";
    		if(!_access(names[i].c_str(),0))
    		{
    			if(!rename(names[i].c_str(),new_name.c_str()))
    			{
    				cout<<"RENAME "<<names[i]<<" AS: "<<new_name<<""<<endl;
    				names[i] = new_name;
    				//used_names[i] =false;
    			}
    		}
    	}
    	for(int i=0;i<mp3_num;i++)
    		used_names[i] = false;
    	cout<<endl;
    	cout<<"-------------AGAIN RENAME MP3 FILES-------------"<<endl;
    	for(int i=0;i<mp3_num;i++){
    		int new_name_num = -1;
    		while(new_name_num<0){
    			int tmp= rand()%mp3_num;
    			if(!used_names[tmp]){
    				new_name_num = tmp;
    				used_names[tmp] = true;
    			}
    		}
    		char char_tmp[100];
    		itoa(new_name_num,char_tmp,10);
    		string new_name = string(char_tmp)+".mp3";
    		if(!_access(names[i].c_str(),0))
    		{
    			if(!rename(names[i].c_str(),new_name.c_str()))
    			{
    				cout<<"RENAME "<<names[i]<<" AS: "<<new_name<<""<<endl;
    			}
    		}
    	}
    	cout<<endl;
    	return ;
    }



    大功告成啦!

    *有关生成随机序列的改动

    多谢一楼友邻xiucaijiang 的留言,指出来上述方法生成随机序列的效率非常低。确实。上面用的方法是初始化一个序列用来记录已经“用过”的数,如果生成的随机数是已经用过的数。那么就再又一次生成一遍。这样的方法对于生成大小为N的随机序列,生成第一个随机数的期望次数为1次。第二次为N/(N-1)次。第三次为N/(N-2)次,最后一个数期望次数为N次效率确实非常低。xiucaijiang 给出的方法非常好:


    能够这样理解这样的方法:生成随机序列相当于把之前0~N-1排序的N个数随机排列,那么每次我们随机抽出一个来排到后面。也就是第一次在全部N个数里随机抽一个排到最后一位,第二次在前N-1个数里随机抽一个排到倒数第二位。依次类推。由于每次排序每一个数被抽到的概率都是1/N。所以能够觉得终于的序列是随机排的。

    只是这样的方法在实现起来须要做几次不必要的位移,比方上面的样例中,第二次如果抽到了2,由0,1,2,3,5,4变成0,1,3,5,2,4须要把3移到第2位,5移到第三位,2换到第四位。

    这里3和5的移位事实上是不必要的。也就是我们下一次在4个数里随机取,前4个数排列成0,1,3,5还是0,1,5,3是不影响的。

    所以仅仅须要把2和5换位置就可以。

    总结生成随机序列的方法:循环N次,第i(i=0~N-1)次的操作为在前N-i个数中随机选一个数与第N-i-1个数交换位置。

    void generateRandomList(vector<int> & rand_list){
    	int rand_size = rand_list.size();
    	for(int i=0;i<rand_size;i++){
    		rand_list[i] = i;
    	}
    	srand(time(NULL)); 
    	for(int i=0;i<rand_size;i++){
    		int tmp_rand= rand()%(rand_size-i);
    		int tmp = rand_list[tmp_rand];
    		rand_list[tmp_rand] = rand_list[rand_size-1-i];
    		rand_list[rand_size-1-i] = tmp;
    	}
    	return;
    }

    这次仅仅须要随机N次就能够生成不反复的随机序列啦~

    (转载请注明作者和出处:http://blog.csdn.net/xiaowei_cqu 未经同意请勿用于商业用途)



  • 相关阅读:
    asp.net常用的javascript经典例子
    Silverlight学习之——布局系统
    TreeView数据绑定方法
    软件测试:单元测试的一些疑问
    Silverlight学习之——Deep Zoom文件格式概述
    把生活节奏调整得慢一点
    20、Windows内核函数(1)Windows驱动开发详解笔记,字符串
    24、Windows派遣函数(2)Windows驱动开发详解笔记,直接读写方式
    21、Windows内核函数(2)Windows驱动开发详解笔记,文件操作
    27、Windows内核编程,IRP的同步(1)
  • 原文地址:https://www.cnblogs.com/cxchanpin/p/6882571.html
Copyright © 2020-2023  润新知