C++修改文件后缀名;链表循环删除乘积为10的元素

1. 文件名修改

在一个文件目录下,存在相同扩展名 ".stp"的多个文件,对这样的文件名,请修改文件名称,在文件 名称后增加排序标识 "-01" "-02" "-03"...
#include <iostream>
#include <io.h>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

// Input: 目录名称
// Output:文件列表清单

class Findupdate {
public:
    void replaceFileNameList();//遍历文件列表替换文件名
    bool checkFile(string path);//查找路径下所有文件,不存在子文件夹
    bool checkFile_circ(string path, vector<string>& m_vec_file_path_name);//查找路径下所有文件,存在子文件夹

    ~Findupdate()
    {
        m_vec_file_path_name.clear();
    }
    vector<string> m_vec_file_path_name; //文件名路径列表
private:
    bool replaceFileName(string oldFileName, string newFileName);//替换文件名 
    string m_modif_before = ".stp";             //指定修改前的字段
};

bool Findupdate::replaceFileName(string oldFileName, string newFileName)
{
    fstream fs;
    fs.open(oldFileName.c_str());
    if (fs.fail())
    {
        cout << "文件打开失败!" << endl;
        fs.close();
        return false;
    }
    else
    {
        fs.close();
        if (rename(oldFileName.c_str(), newFileName.c_str()) == -1)   //文件重命名
        {
            cout << "文件名修改失败!" << endl;
            return false;
        }
        return true;
    }
    return true;
}

void Findupdate::replaceFileNameList()
{
    int num = 1;
    string ModifyAfterFilds = "";                  //指定修改后的字段
    for (auto name : m_vec_file_path_name)
    {
        //临时文件名用于字符替换
        string newFileName = name;
        int findIndex = name.find(m_modif_before, 1);
        if (findIndex != -1 && findIndex == (name.size()-4))
        {
            ModifyAfterFilds = ".stp-0" + std::to_string(num); 
            num++;
            newFileName = newFileName.replace(findIndex, m_modif_before.size(), ModifyAfterFilds);
            cout << name << endl;
            cout << newFileName << endl;
        }
        else
        {
            continue;
        }        
        int ret = replaceFileName(name, newFileName);
    }
}

bool Findupdate::checkFile(string path)
{
	string EachPath = path;      //临时路径,用于字符拼接
	intptr_t FileHandle;             //文件句柄
	struct _finddata_t FileInfo;     //文件信息

	if ((FileHandle = _findfirst(EachPath.append("\\*").c_str(), &FileInfo)) == -1)
	{
		cout << "未找到文件! " << endl;
		return false;
	}
	else
	{
		while (_findnext(FileHandle, &FileInfo) == 0)
		{
			if (strcmp(FileInfo.name, ".") != 0 && strcmp(FileInfo.name, "..") != 0)
			{
				m_vec_file_path_name.push_back(FileInfo.name);
				cout << "FileName : " << FileInfo.name << endl;
			}
		}
		_findclose(FileHandle);
	}
	return true;
}

bool Findupdate::checkFile_circ(string path, vector<string>& m_vec_file_path_name)
{
	string EachPath = path;      //临时路径,用于字符拼接
	intptr_t FileHandle;             //文件句柄
	struct _finddata_t FileInfo;     //文件信息

	//使用_findfirst查找文件,获取文件信息
	if ((FileHandle = _findfirst(EachPath.append("\\*").c_str(), &FileInfo)) == -1)
	{
		cout << "failed find file! " << endl;
		return false;
	}
	else
	{
		do
		{   // 比较文件类型是否是文件夹
			if ((FileInfo.attrib &  _A_SUBDIR))
			{
				if (strcmp(FileInfo.name, ".") != 0 && strcmp(FileInfo.name, "..") != 0)
				{
					EachPath = path;   //每次从根路径拼接
					//递归调用
					checkFile_circ(EachPath.append("\\").append(FileInfo.name), m_vec_file_path_name);
				}
			}
			else
			{
				EachPath = path;
				m_vec_file_path_name.push_back(EachPath.append("\\").append(FileInfo.name));

				cout << "PATH/FileName : " << EachPath << endl;
			}
		} while (_findnext(FileHandle, &FileInfo) == 0);
		_findclose(FileHandle);
	}
	return true;
}

int main()
{
	string Path = "E:\\xx\\xx";      //自定义路径
    Findupdate f_upate;
	
  //  f_upate.checkFile(Path); //路径下没有子文件夹
    f_upate.checkFile_circ(Path, f_upate.m_vec_file_path_name);
    f_upate.replaceFileNameList();

	system("pause");
	return 0;
}


 

2.链表删除

链表 head 反复 删去链表中由 总乘积 值为 10 的连续节点组成的序列, 直到不存在这样的序列为止,需 考虑各种特殊情况。
#include<iostream>
using namespace std;

struct ListNode {  
    int val;  
    ListNode *next;  
    ListNode(int x) : val(x), next(NULL) {}  
};  

class Solution
{
public:
    // 辅助函数:打印链表  
    void printList(ListNode* head) {  
        while (head) {  
            std::cout << head->val << " ";  
            head = head->next;  
        }  
        std::cout << std::endl;  
    }  
    
    // 辅助函数:创建链表  
    ListNode* createList(int arr[], int n) {  
        if (n == 0) return nullptr;  
        ListNode* head = new ListNode(arr[0]);  
        ListNode* curr = head;  
        for (int i = 1; i < n; ++i) {  
            curr->next = new ListNode(arr[i]);  
            curr = curr->next;  
        }  
        return head;  
    }  
    
    // 辅助函数:释放链表内存  
    void deleteList(ListNode* head) {  
        while (head) {  
            ListNode* temp = head;  
            head = head->next;  
            delete temp;  
        }  
    }  

    ListNode* removeSublists(ListNode* head)
    {
        // 创建一个哑节点作为头节点的前驱  
        ListNode dummy(0);  
        dummy.next = head;  
        ListNode* prev = &dummy;  
        ListNode* curr = head;  
    
        while (curr && curr->next) {  
            // 检查当前节点和下一个节点的乘积是否为10  
            while (curr && curr->next && curr->val * curr->next->val == 10) {  
                // 删除这两个节点  
                prev->next = curr->next->next;  
                // 移动到下一个要检查的节点(注意这里不是curr = prev->next,因为prev->next可能已经被改变了)  
                curr = curr->next;
            }  
            curr = prev->next;  
            // 如果没有找到乘积为10的节点对,则移动到下一个要检查的节点对  
            if (curr) {  
                prev = curr;  
                curr = curr->next;  
            }  
        }  
    
        // 返回哑节点的下一个节点作为新的头节点  
        return dummy.next; 
    }
};
  
int main() {  
    int arr[] = {1, 2, 5, 2, 1, 2, 5}; // 示例链表:1 -> 2 -> 5 -> 2 -> 1 -> 2 -> 5  

    Solution sol_list;
    ListNode* head = sol_list.createList(arr, sizeof(arr) / sizeof(arr[0]));
    std::cout << "Original List: ";  
    sol_list.printList(head);
    head = sol_list.removeSublists(head);  
    std::cout << "List after removing product-ten nodes: ";  
    sol_list.printList(head);  
  
    sol_list.deleteList(head); // 释放链表内存  
    return 0;  
}

上面的解决的范围不全

2024.5.31

修改链表重复删除乘积为10的连续节点。考虑两种特殊情况,情况1,被删除的节点,可能与后面的节点重新形成乘积为10的连续节点,这种都会删除 (相当于区间覆盖,增加了数组的区间范围输出的函数,利用滑动窗口思路来解);情况2 当前链表被删除后,可能会出现,新的乘积为10的连续节点,这种情况,继续删除,如,2,2,5,5,中间,2,5删除后剩下的2,5 还可以被删除。

struct ListNode {  
    int val;  
    ListNode *next;  
    ListNode(int x) : val(x), next(NULL) {}  
};  

class Solution
{
public:
    // 辅助函数:打印链表  
    void printList(ListNode* head) {  
        while (head) {  
            std::cout << head->val << " ";  
            head = head->next;  
        }  
        std::cout << std::endl;  
    }  
    
    // 辅助函数:创建链表  
    ListNode* createList(int arr[], int n) {  
        if (n == 0) return nullptr;  
        ListNode* head = new ListNode(arr[0]);  
        ListNode* curr = head;  
        for (int i = 1; i < n; ++i) {  
            curr->next = new ListNode(arr[i]);  
            curr = curr->next;  
        }  
        return head;  
    }  
    
    // 辅助函数:释放链表内存  
    void deleteList(ListNode* head) {  
        while (head) {  
            ListNode* temp = head;  
            head = head->next;  
            delete temp;  
        }  
    }  

    bool check(ListNode* head)
    {
       // 创建一个哑节点作为头节点的前驱  
        ListNode dummy(0);  
        dummy.next = head;
        ListNode* prev = head;
        ListNode* cur = head;
        int prod = 1;
        while(cur)
        {
            prod*= cur->val;
            while(prev != cur && abs(prod) > 10)
            {
                prod /= prev->val;
                prev = prev->next;
            }
            if(prod == 10)
            {
                return true;
            }
            cur = cur->next;
        }
        return false; 
    }
    //利用滑动窗口模型,采用双指针,找到需要删除的范围
    //范围可能出现交叉或者覆盖,暂时用map 保存每个节点指针,方便后期删除
    ListNode* removeSublists(ListNode* head)
    {
        ListNode dummy(0);  
        dummy.next = head;
        ListNode* prev = head;
        ListNode* cur = head;
        map<ListNode*, int> m_p;
        int prod = 1;
        while(cur)
        {
            prod*= cur->val;
            while(prev != cur && abs(prod) > 10)
            {
                prod /= prev->val;
                prev = prev->next;
            }
            if(prod == 10)
            {
                ListNode* tp = prev;
                while(tp != cur)
                {
                   m_p[tp] = tp->val;
                   tp = tp->next;
                }
                m_p[cur] = cur->val;
            }
            cur = cur->next;
        }
        ListNode* p_r = &dummy;//最终需要删除的指针
        ListNode* p_rp = head;//遍历
        while(p_rp)
        {
            if(m_p.count(p_rp) == 0)
            {   
                p_r->next = p_rp;
                p_r = p_r->next;
            }
            p_rp = p_rp->next;
        }
        p_r->next = p_rp;
        map<ListNode*, int>().swap(m_p);
        return dummy.next;
    }

    void fun(int* nums, int numsSize)
    {//测试数组中符合的乘积,输出范围
        //滑动窗口数数组模型
        int ret = 0;
        int prod = 1, i = 0;
        for (int j = 0; j < numsSize; j++) {
            prod *= nums[j];
            while (i <= j && abs(prod) > 10) {
                prod /= nums[i];
                i++;
            }
            //cout << prod << endl;
            if(prod == 10){
                cout <<"范围: " << i << " " << j <<";";
            }
        }
    }

};

3. VS Code 配置 gitee

在VScode上配置Git - 知乎

Gitee 源码

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值